Skip to content
Snippets Groups Projects
Commit 4a468910 authored by Ryan Izard's avatar Ryan Izard
Browse files

Firewall working and unit tests working. Found an fixed a couple bugs in the...

Firewall working and unit tests working. Found an fixed a couple bugs in the Firewall during the process.
parent e4309727
No related branches found
No related tags found
No related merge requests found
...@@ -31,6 +31,7 @@ import org.projectfloodlight.openflow.protocol.OFVersion; ...@@ -31,6 +31,7 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.match.MatchField; import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.DatapathId;
import org.projectfloodlight.openflow.types.EthType; import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IPv4AddressWithMask; import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
import org.projectfloodlight.openflow.types.IpProtocol; import org.projectfloodlight.openflow.types.IpProtocol;
import org.projectfloodlight.openflow.types.MacAddress; import org.projectfloodlight.openflow.types.MacAddress;
...@@ -80,7 +81,7 @@ public class Firewall implements IFirewallService, IOFMessageListener, ...@@ -80,7 +81,7 @@ public class Firewall implements IFirewallService, IOFMessageListener,
protected List<FirewallRule> rules; // protected by synchronized protected List<FirewallRule> rules; // protected by synchronized
protected boolean enabled; protected boolean enabled;
protected int subnet_mask = IPv4.toIPv4Address("255.255.255.0"); protected IPv4Address subnet_mask = IPv4Address.of("255.255.255.0");
// constant strings for storage/parsing // constant strings for storage/parsing
public static final String TABLE_NAME = "controller_firewallrules"; public static final String TABLE_NAME = "controller_firewallrules";
...@@ -349,14 +350,14 @@ public class Firewall implements IFirewallService, IOFMessageListener, ...@@ -349,14 +350,14 @@ public class Firewall implements IFirewallService, IOFMessageListener,
@Override @Override
public String getSubnetMask() { public String getSubnetMask() {
return IPv4.fromIPv4Address(this.subnet_mask); return this.subnet_mask.toString();
} }
@Override @Override
public void setSubnetMask(String newMask) { public void setSubnetMask(String newMask) {
if (newMask.trim().isEmpty()) if (newMask.trim().isEmpty())
return; return;
this.subnet_mask = IPv4.toIPv4Address(newMask.trim()); this.subnet_mask = IPv4Address.of(newMask.trim());
} }
@Override @Override
...@@ -497,10 +498,10 @@ public class Firewall implements IFirewallService, IOFMessageListener, ...@@ -497,10 +498,10 @@ public class Firewall implements IFirewallService, IOFMessageListener,
* the IP address to check * the IP address to check
* @return true if it is a broadcast address, false otherwise * @return true if it is a broadcast address, false otherwise
*/ */
protected boolean IPIsBroadcast(int IPAddress) { protected boolean isIPBroadcast(IPv4Address ip) {
// inverted subnet mask // inverted subnet mask
int inv_subnet_mask = ~this.subnet_mask; IPv4Address inv_subnet_mask = subnet_mask.not();
return ((IPAddress & inv_subnet_mask) == inv_subnet_mask); return ip.and(inv_subnet_mask).equals(inv_subnet_mask);
} }
public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) { public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
...@@ -511,9 +512,9 @@ public class Firewall implements IFirewallService, IOFMessageListener, ...@@ -511,9 +512,9 @@ public class Firewall implements IFirewallService, IOFMessageListener,
// broadcasts -> L2 broadcast + L3 unicast) // broadcasts -> L2 broadcast + L3 unicast)
if (eth.isBroadcast() == true) { if (eth.isBroadcast() == true) {
boolean allowBroadcast = true; boolean allowBroadcast = true;
// the case to determine if we have L2 broadcast + L3 unicast // the case to determine if we have L2 broadcast + L3 unicast (L3 broadcast default set to /24 or 255.255.255.0)
// don't allow this broadcast packet if such is the case (malformed packet) // don't allow this broadcast packet if such is the case (malformed packet)
if ((eth.getPayload() instanceof IPv4) && (((IPv4) eth.getPayload()).getDestinationAddress().isBroadcast() == false)) { if ((eth.getPayload() instanceof IPv4) && !isIPBroadcast(((IPv4) eth.getPayload()).getDestinationAddress())) {
allowBroadcast = false; allowBroadcast = false;
} }
if (allowBroadcast == true) { if (allowBroadcast == true) {
......
...@@ -22,7 +22,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; ...@@ -22,7 +22,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.projectfloodlight.openflow.protocol.match.MatchField; import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.DatapathId;
import org.projectfloodlight.openflow.types.EthType; import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IPv4AddressWithMask; import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
import org.projectfloodlight.openflow.types.IpProtocol; import org.projectfloodlight.openflow.types.IpProtocol;
import org.projectfloodlight.openflow.types.MacAddress; import org.projectfloodlight.openflow.types.MacAddress;
...@@ -37,7 +36,95 @@ import net.floodlightcontroller.packet.UDP; ...@@ -37,7 +36,95 @@ import net.floodlightcontroller.packet.UDP;
@JsonSerialize(using=FirewallRuleSerializer.class) @JsonSerialize(using=FirewallRuleSerializer.class)
public class FirewallRule implements Comparable<FirewallRule> { public class FirewallRule implements Comparable<FirewallRule> {
public int ruleid; @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FirewallRule other = (FirewallRule) obj;
if (action != other.action)
return false;
if (any_dl_dst != other.any_dl_dst)
return false;
if (any_dl_src != other.any_dl_src)
return false;
if (any_dl_type != other.any_dl_type)
return false;
if (any_dpid != other.any_dpid)
return false;
if (any_in_port != other.any_in_port)
return false;
if (any_nw_dst != other.any_nw_dst)
return false;
if (any_nw_proto != other.any_nw_proto)
return false;
if (any_nw_src != other.any_nw_src)
return false;
if (any_tp_dst != other.any_tp_dst)
return false;
if (any_tp_src != other.any_tp_src)
return false;
if (dl_dst == null) {
if (other.dl_dst != null)
return false;
} else if (!dl_dst.equals(other.dl_dst))
return false;
if (dl_src == null) {
if (other.dl_src != null)
return false;
} else if (!dl_src.equals(other.dl_src))
return false;
if (dl_type == null) {
if (other.dl_type != null)
return false;
} else if (!dl_type.equals(other.dl_type))
return false;
if (dpid == null) {
if (other.dpid != null)
return false;
} else if (!dpid.equals(other.dpid))
return false;
if (in_port == null) {
if (other.in_port != null)
return false;
} else if (!in_port.equals(other.in_port))
return false;
if (nw_dst_prefix_and_mask == null) {
if (other.nw_dst_prefix_and_mask != null)
return false;
} else if (!nw_dst_prefix_and_mask.equals(other.nw_dst_prefix_and_mask))
return false;
if (nw_proto == null) {
if (other.nw_proto != null)
return false;
} else if (!nw_proto.equals(other.nw_proto))
return false;
if (nw_src_prefix_and_mask == null) {
if (other.nw_src_prefix_and_mask != null)
return false;
} else if (!nw_src_prefix_and_mask.equals(other.nw_src_prefix_and_mask))
return false;
if (priority != other.priority)
return false;
if (ruleid != other.ruleid)
return false;
if (tp_dst == null) {
if (other.tp_dst != null)
return false;
} else if (!tp_dst.equals(other.tp_dst))
return false;
if (tp_src == null) {
if (other.tp_src != null)
return false;
} else if (!tp_src.equals(other.tp_src))
return false;
return true;
}
public int ruleid;
public DatapathId dpid; public DatapathId dpid;
public OFPort in_port; public OFPort in_port;
...@@ -81,18 +168,16 @@ public class FirewallRule implements Comparable<FirewallRule> { ...@@ -81,18 +168,16 @@ public class FirewallRule implements Comparable<FirewallRule> {
* The default rule is to match on anything. * The default rule is to match on anything.
*/ */
public FirewallRule() { public FirewallRule() {
this.dpid = DatapathId.NONE;
this.in_port = OFPort.ANY; this.in_port = OFPort.ANY;
this.dl_src = MacAddress.NONE; this.dl_src = MacAddress.NONE;
this.nw_src_prefix_and_mask = IPv4AddressWithMask.NONE;
//this.nw_src_maskbits = 0;
this.dl_dst = MacAddress.NONE; this.dl_dst = MacAddress.NONE;
this.dl_type = EthType.NONE;
this.nw_src_prefix_and_mask = IPv4AddressWithMask.NONE;
this.nw_dst_prefix_and_mask = IPv4AddressWithMask.NONE;
this.nw_proto = IpProtocol.NONE; this.nw_proto = IpProtocol.NONE;
this.tp_src = TransportPort.NONE; this.tp_src = TransportPort.NONE;
this.tp_dst = TransportPort.NONE; this.tp_dst = TransportPort.NONE;
this.dl_dst = MacAddress.NONE;
this.nw_dst_prefix_and_mask = IPv4AddressWithMask.NONE;
//this.nw_dst_maskbits = 0;
this.dpid = DatapathId.NONE;
this.any_dpid = true; this.any_dpid = true;
this.any_in_port = true; this.any_in_port = true;
this.any_dl_src = true; this.any_dl_src = true;
...@@ -267,7 +352,7 @@ public class FirewallRule implements Comparable<FirewallRule> { ...@@ -267,7 +352,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
pkt_ip = (IPv4) pkt; pkt_ip = (IPv4) pkt;
// IP addresses (src and dst) match? // IP addresses (src and dst) match?
if (any_nw_src == false && this.matchIPAddress(nw_src_prefix_and_mask.getValue().getInt(), nw_src_prefix_and_mask.getMask().getInt(), pkt_ip.getSourceAddress()) == false) if (any_nw_src == false && !nw_src_prefix_and_mask.matches(pkt_ip.getSourceAddress()))
return false; return false;
if (action == FirewallRule.FirewallAction.DROP) { if (action == FirewallRule.FirewallAction.DROP) {
//wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL; //wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL;
...@@ -279,7 +364,7 @@ public class FirewallRule implements Comparable<FirewallRule> { ...@@ -279,7 +364,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
adp.allow.setMasked(MatchField.IPV4_SRC, nw_src_prefix_and_mask); adp.allow.setMasked(MatchField.IPV4_SRC, nw_src_prefix_and_mask);
} }
if (any_nw_dst == false && this.matchIPAddress(nw_dst_prefix_and_mask.getValue().getInt(), nw_dst_prefix_and_mask.getMask().getInt(), pkt_ip.getDestinationAddress()) == false) if (any_nw_dst == false && !nw_dst_prefix_and_mask.matches(pkt_ip.getDestinationAddress()))
return false; return false;
if (action == FirewallRule.FirewallAction.DROP) { if (action == FirewallRule.FirewallAction.DROP) {
//wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL; //wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL;
...@@ -386,71 +471,40 @@ public class FirewallRule implements Comparable<FirewallRule> { ...@@ -386,71 +471,40 @@ public class FirewallRule implements Comparable<FirewallRule> {
return true; return true;
} }
/**
* Determines if rule's CIDR address matches IP address of the packet
*
* @param rulePrefix
* prefix part of the CIDR address
* @param ruleBits
* the size of mask of the CIDR address
* @param packetAddress
* the IP address of the incoming packet to match with
* @return true if CIDR address matches the packet's IP address, false
* otherwise
*/
protected boolean matchIPAddress(int rulePrefix, int ruleBits, IPv4Address packetAddress) {
boolean matched = true;
int rule_iprng = 32 - ruleBits;
int rule_ipint = rulePrefix;
int pkt_ipint = packetAddress.getInt();
// if there's a subnet range (bits to be wildcarded > 0)
if (rule_iprng > 0) {
// right shift bits to remove rule_iprng of LSB that are to be
// wildcarded
rule_ipint = rule_ipint >> rule_iprng;
pkt_ipint = pkt_ipint >> rule_iprng;
// now left shift to return to normal range, except that the
// rule_iprng number of LSB
// are now zeroed
rule_ipint = rule_ipint << rule_iprng;
pkt_ipint = pkt_ipint << rule_iprng;
}
// check if we have a match
if (rule_ipint != pkt_ipint)
matched = false;
return matched;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 2521; final int prime = 31;
int result = super.hashCode(); int result = 1;
result = prime * result + (int) dpid.getLong(); result = prime * result + ((action == null) ? 0 : action.hashCode());
result = prime * result + in_port.getPortNumber(); result = prime * result + (any_dl_dst ? 1231 : 1237);
result = prime * result + (int) dl_src.getLong(); result = prime * result + (any_dl_src ? 1231 : 1237);
result = prime * result + (int) dl_dst.getLong(); result = prime * result + (any_dl_type ? 1231 : 1237);
result = prime * result + dl_type.getValue(); result = prime * result + (any_dpid ? 1231 : 1237);
result = prime * result + nw_src_prefix_and_mask.getValue().getInt(); result = prime * result + (any_in_port ? 1231 : 1237);
result = prime * result + nw_src_prefix_and_mask.getMask().getInt(); result = prime * result + (any_nw_dst ? 1231 : 1237);
result = prime * result + nw_dst_prefix_and_mask.getValue().getInt(); result = prime * result + (any_nw_proto ? 1231 : 1237);
result = prime * result + nw_dst_prefix_and_mask.getMask().getInt(); result = prime * result + (any_nw_src ? 1231 : 1237);
result = prime * result + nw_proto.getIpProtocolNumber(); result = prime * result + (any_tp_dst ? 1231 : 1237);
result = prime * result + tp_src.getPort(); result = prime * result + (any_tp_src ? 1231 : 1237);
result = prime * result + tp_dst.getPort(); result = prime * result + ((dl_dst == null) ? 0 : dl_dst.hashCode());
result = prime * result + action.ordinal(); result = prime * result + ((dl_src == null) ? 0 : dl_src.hashCode());
result = prime * result + priority; result = prime * result + ((dl_type == null) ? 0 : dl_type.hashCode());
result = prime * result + (new Boolean(any_dpid)).hashCode(); result = prime * result + ((dpid == null) ? 0 : dpid.hashCode());
result = prime * result + (new Boolean(any_in_port)).hashCode(); result = prime * result + ((in_port == null) ? 0 : in_port.hashCode());
result = prime * result + (new Boolean(any_dl_src)).hashCode(); result = prime
result = prime * result + (new Boolean(any_dl_dst)).hashCode(); * result
result = prime * result + (new Boolean(any_dl_type)).hashCode(); + ((nw_dst_prefix_and_mask == null) ? 0
result = prime * result + (new Boolean(any_nw_src)).hashCode(); : nw_dst_prefix_and_mask.hashCode());
result = prime * result + (new Boolean(any_nw_dst)).hashCode(); result = prime * result
result = prime * result + (new Boolean(any_nw_proto)).hashCode(); + ((nw_proto == null) ? 0 : nw_proto.hashCode());
result = prime * result + (new Boolean(any_tp_src)).hashCode(); result = prime
result = prime * result + (new Boolean(any_tp_dst)).hashCode(); * result
return result; + ((nw_src_prefix_and_mask == null) ? 0
} : nw_src_prefix_and_mask.hashCode());
result = prime * result + priority;
result = prime * result + ruleid;
result = prime * result + ((tp_dst == null) ? 0 : tp_dst.hashCode());
result = prime * result + ((tp_src == null) ? 0 : tp_src.hashCode());
return result;
}
} }
...@@ -273,19 +273,19 @@ public class FirewallTest extends FloodlightTestCase { ...@@ -273,19 +273,19 @@ public class FirewallTest extends FloodlightTestCase {
List<FirewallRule> rules = firewall.readRulesFromStorage(); List<FirewallRule> rules = firewall.readRulesFromStorage();
// verify rule 1 // verify rule 1
FirewallRule r = rules.get(0); FirewallRule r = rules.get(0);
assertEquals(r.in_port, 2); assertEquals(r.in_port, OFPort.of(2));
assertEquals(r.priority, 1); assertEquals(r.priority, 1);
assertEquals(r.dl_src, MacAddress.of("00:00:00:00:00:01")); assertEquals(r.dl_src, MacAddress.of("00:00:00:00:00:01"));
assertEquals(r.dl_dst, MacAddress.of("00:00:00:00:00:02")); assertEquals(r.dl_dst, MacAddress.of("00:00:00:00:00:02"));
assertEquals(r.action, FirewallRule.FirewallAction.DROP); assertEquals(r.action, FirewallRule.FirewallAction.DROP);
// verify rule 2 // verify rule 2
r = rules.get(1); r = rules.get(1);
assertEquals(r.in_port, 3); assertEquals(r.in_port, OFPort.of(3));
assertEquals(r.priority, 2); assertEquals(r.priority, 2);
assertEquals(r.dl_src, MacAddress.of("00:00:00:00:00:02")); assertEquals(r.dl_src, MacAddress.of("00:00:00:00:00:02"));
assertEquals(r.dl_dst, MacAddress.of("00:00:00:00:00:01")); assertEquals(r.dl_dst, MacAddress.of("00:00:00:00:00:01"));
assertEquals(r.nw_proto, IpProtocol.TCP); assertEquals(r.nw_proto, IpProtocol.TCP);
assertEquals(r.tp_dst, 80); assertEquals(r.tp_dst, TransportPort.of(80));
assertEquals(r.any_nw_proto, false); assertEquals(r.any_nw_proto, false);
assertEquals(r.action, FirewallRule.FirewallAction.ALLOW); assertEquals(r.action, FirewallRule.FirewallAction.ALLOW);
} }
...@@ -358,7 +358,7 @@ public class FirewallTest extends FloodlightTestCase { ...@@ -358,7 +358,7 @@ public class FirewallTest extends FloodlightTestCase {
rule.nw_proto = IpProtocol.TCP; rule.nw_proto = IpProtocol.TCP;
rule.any_nw_proto = false; rule.any_nw_proto = false;
// source is IP 192.168.1.2 // source is IP 192.168.1.2
rule.nw_src_prefix_and_mask = IPv4AddressWithMask.of("192.168.1.2/24"); rule.nw_src_prefix_and_mask = IPv4AddressWithMask.of("192.168.1.2/32");
rule.any_nw_src = false; rule.any_nw_src = false;
// dest is network 192.168.1.0/24 // dest is network 192.168.1.0/24
rule.nw_dst_prefix_and_mask = IPv4AddressWithMask.of("192.168.1.0/24"); rule.nw_dst_prefix_and_mask = IPv4AddressWithMask.of("192.168.1.0/24");
...@@ -373,7 +373,7 @@ public class FirewallTest extends FloodlightTestCase { ...@@ -373,7 +373,7 @@ public class FirewallTest extends FloodlightTestCase {
verify(sw); verify(sw);
IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION); IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD); assertEquals(IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD, decision.getRoutingAction());
// clear decision // clear decision
IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION); IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
...@@ -383,7 +383,7 @@ public class FirewallTest extends FloodlightTestCase { ...@@ -383,7 +383,7 @@ public class FirewallTest extends FloodlightTestCase {
verify(sw); verify(sw);
decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION); decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP); assertEquals(IRoutingDecision.RoutingAction.DROP, decision.getRoutingAction());
} }
@Test @Test
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment