Skip to content
Snippets Groups Projects
Commit 01b9fa80 authored by Pengfei Lu's avatar Pengfei Lu
Browse files

add new ACL application and test code

parent b09f60c5
No related branches found
No related tags found
No related merge requests found
Showing
with 3343 additions and 0 deletions
package net.floodlightcontroller.accesscontrollist;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.floodlightcontroller.accesscontrollist.ACLRule.Action;
import net.floodlightcontroller.accesscontrollist.ap.AP;
import net.floodlightcontroller.accesscontrollist.ap.APManager;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.accesscontrollist.web.ACLWebRoutable;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.devicemanager.IDeviceListener;
import net.floodlightcontroller.devicemanager.IDeviceService;
import net.floodlightcontroller.devicemanager.SwitchPort;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
import net.floodlightcontroller.storage.IStorageSourceService;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ACL implements IACLService, IFloodlightModule, IDeviceListener {
// service modules needed
protected IRestApiService restApi;
protected IDeviceService deviceManager;
protected IStorageSourceService storageSource;
protected static Logger logger;
private APManager apManager;
// variable used
private int lastRuleId = 1; // rule id counter
private List<ACLRule> ruleSet;
private Map<String, Integer> dpid2FlowPriority;
private Map<Integer, Set<String>> ruleId2Dpid;
private Map<Integer, Set<String>> ruleId2FlowName;
/**
* used by REST API to query ACL rules
*/
@Override
public List<ACLRule> getRules() {
return this.ruleSet;
}
/**
* check if the new rule matches an existing rule
*/
private boolean checkRuleMatch(ACLRule newRule) {
Iterator<ACLRule> iter = ruleSet.iterator();
while (iter.hasNext()) {
ACLRule existingRule = iter.next();
if(newRule.match(existingRule)){
logger.error("existing rule: " + existingRule);
return true;
}
}
return false;
}
/**
* used by REST API to add ACL rule
* @return if the new ACL rule is added successfully
*/
@Override
public boolean addRule(ACLRule rule) {
if(checkRuleMatch(rule)){
return false;
}
rule.setId(lastRuleId++);
this.ruleSet.add(rule);
logger.info("No.{} ACL rule added.", rule.getId());
enforceAddedRule(rule);
return true;
}
/**
* used by REST API to remove ACL rule
*/
@Override
public void removeRule(int ruleid) {
Iterator<ACLRule> iter = this.ruleSet.iterator();
while (iter.hasNext()) {
ACLRule rule = iter.next();
if (rule.getId() == ruleid) { iter.remove();
break;
}
}
logger.info("No.{} ACL rule removed.", ruleid);
enforceRemovedRule(ruleid);
}
/**
* used by REST API to clear ACL
*/
@Override
public void removeAllRules() {
this.lastRuleId = 1;
this.ruleSet = new ArrayList<ACLRule>();
this.dpid2FlowPriority = new HashMap<String, Integer>();
this.ruleId2Dpid = new HashMap<Integer, Set<String>>();
Iterator<Integer> ruleIdIter = ruleId2FlowName.keySet().iterator();
while (ruleIdIter.hasNext()) {
int ruleId = ruleIdIter.next();
Set<String> flowNameSet = ruleId2FlowName.get(ruleId);
logger.info("No.{} ACL rule removed.", ruleId);
for (String flowName : flowNameSet) {
removeFlow(flowName);
logger.info("ACL flow {} removed.", flowName);
}
}
this.ruleId2FlowName = new HashMap<Integer, Set<String>>();
}
/**
* enforce new added rule
*/
private void enforceAddedRule(ACLRule rule) {
Set<String> dpidSet;
if (rule.getNw_src() != null) {
dpidSet = apManager.getDpidSet(rule.getNw_src_prefix(),rule.getNw_src_maskbits());
} else {
dpidSet = apManager.getDpidSet(rule.getNw_dst_prefix(),rule.getNw_dst_maskbits());
}
Iterator<String> dpidIter = dpidSet.iterator();
Set<String> nameSet = new HashSet<String>();
while (dpidIter.hasNext()) {
String dpid = dpidIter.next();
String flowName = "ACLRule_" + rule.getId() + "_" + dpid;
generateFlow(rule, dpid, flowName);
nameSet.add(flowName);
}
ruleId2FlowName.put(rule.getId(), nameSet);
ruleId2Dpid.put(rule.getId(), dpidSet);
}
/**
* enforce removed rule
*/
private void enforceRemovedRule(int ruleId) {
Set<String> flowEntryName = ruleId2FlowName.get(ruleId);
Iterator<String> iter = flowEntryName.iterator();
while (iter.hasNext()) {
String name = iter.next();
removeFlow(name);
logger.info("ACL flow " + name + " removed.");
}
}
/**
* generate and push ACL flow entry
*/
private void generateFlow(ACLRule rule, String dpid, String flowName) {
int priority;
// get priority for the new flow entry
if (dpid2FlowPriority.get(dpid) == null) {
dpid2FlowPriority.put(dpid, 30000);
priority = 30000;
} else {
priority = dpid2FlowPriority.get(dpid);
}
if (rule.getNw_src() != null) {
HashMap<String,Object> flow = new HashMap<String,Object>();
flow.put(StaticFlowEntryPusher.COLUMN_SWITCH, dpid);
flow.put(StaticFlowEntryPusher.COLUMN_NAME, flowName);
flow.put(StaticFlowEntryPusher.COLUMN_ACTIVE, Boolean.toString(true));
flow.put(StaticFlowEntryPusher.COLUMN_COOKIE, "0");
flow.put(StaticFlowEntryPusher.COLUMN_PRIORITY, Integer.toString(priority));
dpid2FlowPriority.put(dpid, --priority);
flow.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, "2048");
flow.put(StaticFlowEntryPusher.COLUMN_NW_SRC, rule.getNw_src());
// process for the nw_dst attribute
if (rule.getNw_dst() != null) {
flow.put(StaticFlowEntryPusher.COLUMN_NW_DST, rule.getNw_dst());
}
if (rule.getNw_proto() != 0) {
flow.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, Integer.toString(rule.getNw_proto()));
}
if (rule.getAction() == Action.ALLOW) {
flow.put(StaticFlowEntryPusher.COLUMN_ACTIONS, "output=controller");
}
if (rule.getTp_dst() != 0) {
flow.put(StaticFlowEntryPusher.COLUMN_TP_DST, Integer.toString(rule.getTp_dst()));
}
storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, flow);
} else {
HashMap<String,Object> flow = new HashMap<String,Object>();
flow.put(StaticFlowEntryPusher.COLUMN_SWITCH, dpid);
flow.put(StaticFlowEntryPusher.COLUMN_NAME, flowName);
flow.put(StaticFlowEntryPusher.COLUMN_ACTIVE, Boolean.toString(true));
flow.put(StaticFlowEntryPusher.COLUMN_COOKIE, "0");
flow.put(StaticFlowEntryPusher.COLUMN_PRIORITY, Integer.toString(priority));
dpid2FlowPriority.put(dpid, --priority);
flow.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, "2048");
flow.put(StaticFlowEntryPusher.COLUMN_NW_DST, rule.getNw_dst());
if (rule.getNw_proto() != 0) {
flow.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, Integer.toString(rule.getNw_proto()));
}
if (rule.getAction() == Action.ALLOW) {
flow.put(StaticFlowEntryPusher.COLUMN_ACTIONS, "output=controller");
}
if (rule.getTp_dst() != 0) {
flow.put(StaticFlowEntryPusher.COLUMN_TP_DST, Integer.toString(rule.getTp_dst()));
}
storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, flow);
}
logger.info("ACL flow " + flowName + " added in " + dpid);
}
/**
* remove ACL flow entry
*/
private void removeFlow(String name) {
storageSource.deleteRowAsync("controller_staticflowtableentry", name);
}
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
l.add(IACLService.class);
return l;
}
@Override
public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
// We are the class that implements the service
m.put(IACLService.class, this);
return m;
}
@Override
public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
l.add(IRestApiService.class);
l.add(IDeviceService.class);
return l;
}
@Override
public void init(FloodlightModuleContext context)
throws FloodlightModuleException {
restApi = context.getServiceImpl(IRestApiService.class);
deviceManager = context.getServiceImpl(IDeviceService.class);
logger = LoggerFactory.getLogger(ACL.class);
storageSource = context.getServiceImpl(IStorageSourceService.class);
ruleSet = new ArrayList<ACLRule>();
apManager = new APManager();
ruleId2FlowName = new HashMap<Integer, Set<String>>();
ruleId2Dpid = new HashMap<Integer, Set<String>>();
dpid2FlowPriority = new HashMap<String, Integer>();
}
@Override
public void startUp(FloodlightModuleContext context) {
// register REST interface
restApi.addRestletRoutable(new ACLWebRoutable());
deviceManager.addListener(this);
}
/**
* listen for new device
*/
@Override
public void deviceAdded(IDevice device) {
SwitchPort[] switchPort = device.getAttachmentPoints();
IPv4Address[] ips = device.getIPv4Addresses();
if(ips.length == 0){
// A new no-ip device added
return;
}
String dpid = HexString.toHexString(switchPort[0].getSwitchDPID().getLong());
String ip = IPv4.fromIPv4Address(ips[0].getInt());
logger.info("New AP added. [dpid:" + dpid + " ip:" + ip + "]");
AP ap = new AP(ip,dpid);
apManager.addAP(ap);
processAPAdded(ap);
}
/**
* push ACL flow given the new device
*/
private void processAPAdded(AP ap) {
String dpid = ap.getDpid();
int ip = IPv4.toIPv4Address(ap.getIp());
Iterator<ACLRule> iter = this.ruleSet.iterator();
while (iter.hasNext()) {
ACLRule rule = iter.next();
if (rule.getNw_src() != null) {
if (IPAddressUtil.containIP(rule.getNw_src_prefix(),
rule.getNw_src_maskbits(), ip)) {
// check if there is a flow entry in the switch for the rule
if (ruleId2Dpid.get(rule.getId()).contains(dpid)) {
continue;
}
String flowName = "ACLRule_" + rule.getId() + "_" + dpid;
ruleId2FlowName.get(rule.getId()).add(flowName);
ruleId2Dpid.get(rule.getId()).add(dpid);
generateFlow(rule, dpid, flowName);
}
} else {
if (IPAddressUtil.containIP(rule.getNw_dst_prefix(),
rule.getNw_dst_maskbits(), ip)) {
// check if there is a flow entry in the switch for the rule
if (ruleId2Dpid.get(rule.getId()).contains(dpid)) {
continue;
}
String flowName = "ACLRule_" + rule.getId() + "_" + dpid;
ruleId2FlowName.get(rule.getId()).add(flowName);
ruleId2Dpid.get(rule.getId()).add(dpid);
generateFlow(rule, dpid, flowName);
}
}
}
}
@Override
public void deviceRemoved(IDevice device) {
}
@Override
public void deviceMoved(IDevice device) {
}
@Override
public void deviceIPV4AddrChanged(IDevice device) {
SwitchPort[] switchPort = device.getAttachmentPoints();
IPv4Address[] ips = device.getIPv4Addresses();
String dpid = HexString.toHexString(switchPort[0].getSwitchDPID().getLong());
String ip = null;
// some device may first appear with no IP address(default set to 0.0.0.0), ignore it
for(IPv4Address i : ips){
if(i.getInt() != 0){
ip = IPv4.fromIPv4Address(i.getInt());
break;
}
}
logger.info("New AP added. [dpid:" + dpid + " ip:" + ip + "]");
AP ap = new AP(ip, dpid);
apManager.addAP(ap);
processAPAdded(ap);
}
@Override
public void deviceVlanChanged(IDevice device) {
}
@Override
public String getName() {
return null;
}
@Override
public boolean isCallbackOrderingPrereq(String type, String name) {
return false;
}
@Override
public boolean isCallbackOrderingPostreq(String type, String name) {
return false;
}
}
package net.floodlightcontroller.accesscontrollist;
import static net.floodlightcontroller.accesscontrollist.util.IPAddressUtil.isSubnet;
public class ACLRule {
private int id;
private String nw_src; // CIDR IP address
private String nw_dst; // CIDR IP address
private int nw_src_prefix;
private int nw_src_maskbits;
private int nw_dst_prefix;
private int nw_dst_maskbits;
private int nw_proto;
private int tp_dst;
private Action action;
public enum Action {
DENY, ALLOW
}
public ACLRule() {
this.id = 0;
this.nw_src = null;
this.nw_dst = null;
this.nw_src_prefix = 0;
this.nw_src_maskbits = 0;
this.nw_dst_prefix = 0;
this.nw_dst_maskbits = 0;
this.nw_proto = 0;
this.tp_dst = 0;
this.action = Action.DENY;
}
/**
* check if this rule matches an existing rule:
* a matching means this rule won't take effect at all for reason that
* its working scope is already covered by an existing rule
*/
public boolean match(ACLRule r) {
if ((this.tp_dst == r.tp_dst || r.tp_dst == 0)
&& (this.nw_proto == r.nw_proto || r.nw_proto == 0)
&& (isSubnet(this.getNw_src(), r.getNw_src()) == true)
&& (isSubnet(this.getNw_dst(), r.getNw_dst()) == true)) {
return true;
}
return false;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setNw_src(String nw_src) {
this.nw_src = nw_src;
}
public String getNw_src() {
return nw_src;
}
public void setNw_dst(String nw_dst) {
this.nw_dst = nw_dst;
}
public String getNw_dst() {
return nw_dst;
}
public int getNw_src_prefix() {
return nw_src_prefix;
}
public void setNw_src_prefix(int nw_src_prefix) {
this.nw_src_prefix = nw_src_prefix;
}
public int getNw_src_maskbits() {
return nw_src_maskbits;
}
public void setNw_src_maskbits(int nw_src_maskbits) {
this.nw_src_maskbits = nw_src_maskbits;
}
public int getNw_dst_prefix() {
return nw_dst_prefix;
}
public void setNw_dst_prefix(int nw_dst_prefix) {
this.nw_dst_prefix = nw_dst_prefix;
}
public int getNw_dst_maskbits() {
return nw_dst_maskbits;
}
public void setNw_dst_maskbits(int nw_dst_maskbits) {
this.nw_dst_maskbits = nw_dst_maskbits;
}
public int getNw_proto() {
return nw_proto;
}
/**
* @param nw_proto TCP:6, UDP:11, ICMP:1
*/
public void setNw_proto(int nw_proto) {
this.nw_proto = nw_proto;
}
public int getTp_dst() {
return tp_dst;
}
public void setTp_dst(int tp_dst) {
this.tp_dst = tp_dst;
}
public Action getAction() {
return action;
}
public void setAction(Action action) {
this.action = action;
}
@Override
public String toString() {
return "ACLRule [id=" + id + ", nw_src=" + nw_src + ", nw_dst="
+ nw_dst + ", nw_src_prefix=" + nw_src_prefix
+ ", nw_src_maskbits=" + nw_src_maskbits + ", nw_dst_prefix="
+ nw_dst_prefix + ", nw_dst_maskbits=" + nw_dst_maskbits
+ ", nw_proto=" + nw_proto + ", tp_dst=" + tp_dst + ", action="
+ action + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((action == null) ? 0 : action.hashCode());
result = prime * result + id;
result = prime * result + ((nw_dst == null) ? 0 : nw_dst.hashCode());
result = prime * result + nw_dst_maskbits;
result = prime * result + nw_dst_prefix;
result = prime * result + nw_proto;
result = prime * result + ((nw_src == null) ? 0 : nw_src.hashCode());
result = prime * result + nw_src_maskbits;
result = prime * result + nw_src_prefix;
result = prime * result + tp_dst;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof ACLRule))
return false;
ACLRule other = (ACLRule) obj;
if (action != other.action)
return false;
if (id != other.id)
return false;
if (nw_dst == null) {
if (other.nw_dst != null)
return false;
} else if (!nw_dst.equals(other.nw_dst))
return false;
if (nw_dst_maskbits != other.nw_dst_maskbits)
return false;
if (nw_dst_prefix != other.nw_dst_prefix)
return false;
if (nw_proto != other.nw_proto)
return false;
if (nw_src == null) {
if (other.nw_src != null)
return false;
} else if (!nw_src.equals(other.nw_src))
return false;
if (nw_src_maskbits != other.nw_src_maskbits)
return false;
if (nw_src_prefix != other.nw_src_prefix)
return false;
if (tp_dst != other.tp_dst)
return false;
return true;
}
}
package net.floodlightcontroller.accesscontrollist;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
import net.floodlightcontroller.storage.IStorageSourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FlowPusher implements IFloodlightModule {
protected IFloodlightProviderService floodlightProvider;
protected static Logger logger;
protected IStorageSourceService storageSource;
protected IStaticFlowEntryPusherService sfp;
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
return null;
}
@Override
public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
return null;
}
@Override
public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
l.add(IFloodlightProviderService.class);
l.add(IStaticFlowEntryPusherService.class);
l.add(IStorageSourceService.class);
return l;
}
@Override
public void init(FloodlightModuleContext context)
throws FloodlightModuleException {
floodlightProvider = context
.getServiceImpl(IFloodlightProviderService.class);
storageSource = context.getServiceImpl(IStorageSourceService.class);
sfp = context.getServiceImpl(IStaticFlowEntryPusherService.class);
logger = LoggerFactory.getLogger(FlowPusher.class);
}
@Override
public void startUp(FloodlightModuleContext context)
throws FloodlightModuleException {
HashMap<String,Object> flow = new HashMap<String,Object>();
flow.put(StaticFlowEntryPusher.COLUMN_TP_DST, "80");
flow.put(StaticFlowEntryPusher.COLUMN_NW_DST, "10.0.0.2");
flow.put(StaticFlowEntryPusher.COLUMN_NW_SRC, "10.0.0.1");
flow.put(StaticFlowEntryPusher.COLUMN_PRIORITY, "30001");
flow.put(StaticFlowEntryPusher.COLUMN_NAME, "flow1");
flow.put(StaticFlowEntryPusher.COLUMN_ACTIVE, Boolean.toString(true));
flow.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, "2048");
flow.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, "6");
flow.put(StaticFlowEntryPusher.COLUMN_SWITCH, "00:00:00:00:00:00:00:01");
flow.put(StaticFlowEntryPusher.COLUMN_ACTIONS, "output=controller");
storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, flow);
// flow.put("tp_dst", "80");
// flow.put("nw_dst", "10.0.0.3");
// flow.put("nw_src", "10.0.0.1");
// flow.put("priority", "30001");
// flow.put("name", "flow2");
// flow.put("active", Boolean.toString(true));
// flow.put("dl_type", "2048");
// flow.put("nw_proto", "6");
// flow.put("switch_id", "00:00:00:00:00:00:00:01");
// flow.put("actions", "output=controller");
//
// storageSource.insertRowAsync("controller_staticflowtableentry", flow);
// storageSource.deleteRowAsync("controller_staticflowtableentry", "flow1");
}
}
package net.floodlightcontroller.accesscontrollist;
import java.util.List;
import net.floodlightcontroller.core.module.IFloodlightService;
public interface IACLService extends IFloodlightService {
public List<ACLRule> getRules();
/**
* add a new ACL rule
* @param rule
* @return whether the rule is added successfully
*/
public boolean addRule(ACLRule rule);
public void removeRule(int ruleid);
public void removeAllRules();
}
package net.floodlightcontroller.accesscontrollist.ap;
/**
* Accessing Pair (AP)
* @author Alex
*
*/
public class AP {
private String ip;
private String dpid;
public AP(String ip, String dpid) {
super();
this.ip = ip;
this.dpid = dpid;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getDpid() {
return dpid;
}
public void setDpid(String dpid) {
this.dpid = dpid;
}
@Override
public String toString() {
return "AP [ip=" + ip + ", dpid=" + dpid + "]";
}
}
package net.floodlightcontroller.accesscontrollist.ap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.packet.IPv4;
public class APManager {
private Set<AP> apSet = new HashSet<AP>();
public void addAP(AP ap) {
this.apSet.add(ap);
}
/**
* get dpid set relating to the given CIDR IP
*/
public Set<String> getDpidSet(int cidrPrefix, int cidrMaskBits) {
Set<String> dpidSet = new HashSet<String>();
Iterator<AP> iter = apSet.iterator();
if (cidrMaskBits != 32) {
while (iter.hasNext()) {
AP ap = iter.next();
if (IPAddressUtil.containIP(cidrPrefix, cidrMaskBits,
IPv4.toIPv4Address(ap.getIp()))) {
dpidSet.add(ap.getDpid());
}
}
} else {
while (iter.hasNext()) {
AP ap = iter.next();
if (IPAddressUtil.containIP(cidrPrefix, cidrMaskBits,
IPv4.toIPv4Address(ap.getIp()))) {
dpidSet.add(ap.getDpid());
return dpidSet;
}
}
}
return dpidSet;
}
}
package net.floodlightcontroller.accesscontrollist.test;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import net.floodlightcontroller.accesscontrollist.ACL;
import net.floodlightcontroller.accesscontrollist.ACLRule;
import net.floodlightcontroller.accesscontrollist.IACLService;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.accesscontrollist.web.ACLRuleResource;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
import org.restlet.Context;
public class ACLRuleResourceTest extends FloodlightTestCase {
@Test
public void testJsonToRule(){
// check that all the key-value pairs are specified
String json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
try {
ACLRule rule = ACLRuleResource.jsonToRule(json);
assertEquals(rule.getNw_src(),"10.0.0.1/32");
assertEquals(rule.getNw_dst(),"10.0.0.2/32");
int[] cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
assertEquals(rule.getNw_src_prefix(), cidr[0]);
assertEquals(rule.getNw_src_maskbits(), cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
assertEquals(rule.getNw_dst_prefix(), cidr[0]);
assertEquals(rule.getNw_dst_maskbits(), cidr[1]);
assertEquals(rule.getNw_proto(),6);
assertEquals(rule.getTp_dst(), 80);
} catch (IOException e) {
e.printStackTrace();
}
// check that nw_proto is not specified correctly
json = "{\"nw-prot\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
try {
ACLRule rule = ACLRuleResource.jsonToRule(json);
assertEquals(rule.getNw_src(),"10.0.0.1/32");
assertEquals(rule.getNw_dst(),"10.0.0.2/32");
int[] cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
assertEquals(rule.getNw_src_prefix(), cidr[0]);
assertEquals(rule.getNw_src_maskbits(), cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
assertEquals(rule.getNw_dst_prefix(), cidr[0]);
assertEquals(rule.getNw_dst_maskbits(), cidr[1]);
assertEquals(rule.getNw_proto(),0);
assertEquals(rule.getTp_dst(), 0);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testStore(){
ACL s = new ACL();
FloodlightModuleContext fmc = new FloodlightModuleContext();
try {
s.init(fmc);
} catch (FloodlightModuleException e) {
e.printStackTrace();
}
ACLRuleResource r = new ACLRuleResource();
Context ctx = new Context();
r.init(ctx, null, null);
r.getContext().getAttributes().putIfAbsent(IACLService.class.getCanonicalName(), s);
// input a valid JSON string that adds a new ACL rule
String json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Success! New rule added." + "\"}");
// input a valid JSON string that matches an existing rule
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! The new ACL rule matches an existing rule." + "\"}");
// input a valid JSON string that adds a new ACL rule
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/8\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Success! New rule added." + "\"}");
// input a valid JSON string that matches an existing rule
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.2/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! The new ACL rule matches an existing rule." + "\"}");
// input a invalid JSON string that contains neither nw_src and nw_dst
json = "{\"nw-proto\":\"TCP\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! Either nw_src or nw_dst must be specified." + "\"}");
// input a invalid JSON string that doesn't contain CIDR mask bits
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! " + "CIDR mask bits must be specified." + "\"}");
// input a invalid JSON string that contains a invalid IP address
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.256/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! Octet values in specified IPv4 address must be 0 <= value <= 255" + "\"}");
// input a invalid JSON string that contains a invalid IP address
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.01/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! Specified IPv4 address mustcontain 4 sets of numerical digits separated by periods" + "\"}");
// input a invalid JSON string that contains a invalid CIDR mask bits
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/a\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! CIDR mask bits must be specified as a number(0 ~ 32)." + "\"}");
// input a invalid JSON string that contains a invalid CIDR mask bits
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/33\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! CIDR mask bits must be 0 <= value <= 32." + "\"}");
// input a invalid JSON string that contains a invalid nw-proto value
json = "{\"nw-proto\":\"ARP\",\"src-ip\":\"10.0.0.1/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! nw-proto must be specified as (TCP || UDP || ICMP)." + "\"}");
// input a invalid JSON string that contains a invalid tp-dst value
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"tp-dst\":\"a\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! tp-dst must be specified as a number." + "\"}");
// input a invalid JSON string that contains a invalid action value
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"tp-dst\":\"80\",\"action\":\"PERMIT\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! action must be specidied as (allow || deny)." + "\"}");
}
@Test
public void testRemove(){
ACL s = new ACL();
FloodlightModuleContext fmc = new FloodlightModuleContext();
try {
s.init(fmc);
} catch (FloodlightModuleException e) {
e.printStackTrace();
}
ACLRuleResource r = new ACLRuleResource();
Context ctx = new Context();
r.init(ctx, null, null);
r.getContext().getAttributes().putIfAbsent(IACLService.class.getCanonicalName(), s);
// input a valid JSON string
String json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Success! New rule added." + "\"}");
// input a invalid JSON string that contains a invalid ruleid value
json = "{\"ruleid\":\"a\"}";
assertEquals(r.remove(json),"{\"status\" : \"" + "Failed! ruleid must be specified as a number." + "\"}");
// input a invalid JSON string that contains a non-existing ruleid value
json = "{\"ruleid\":\"2\"}";
assertEquals(r.remove(json),"{\"status\" : \"" + "Failed! a rule with this ID doesn't exist." + "\"}");
// input a valid JSON string that removes an existing ACL rule
json = "{\"ruleid\":\"1\"}";
assertEquals(r.remove(json),"{\"status\" : \"" + "Success! Rule deleted" + "\"}");
}
}
package net.floodlightcontroller.accesscontrollist.test;
import static org.junit.Assert.*;
import net.floodlightcontroller.accesscontrollist.ACLRule;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
public class ACLRuleTest extends FloodlightTestCase{
@Test
public void testMatch(){
int[] cidr = new int[2];
ACLRule rule1, rule2;
// rule1 & rule2 are the same
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule1.setTp_dst(80);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(6);
rule2.setTp_dst(80);
assertTrue(rule1.match(rule2));
// rule1 & rule2 are different in nw_proto
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(11);
assertFalse(rule1.match(rule2));
// rule1's nw_src is a subnet of rule2's nw_src
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(1);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/8");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(1);
assertTrue(rule1.match(rule2));
// rule1's nw_dst is a subnet of rule2's nw_dst
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(1);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/8");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(1);
assertTrue(rule1.match(rule2));
// rule1's nw_src is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
assertTrue(rule1.match(rule2));
// rule1's nw_dst is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
assertTrue(rule1.match(rule2));
// rule1's nw_proto is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
assertTrue(rule1.match(rule2));
// rule1's tp_dst is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule1.setTp_dst(80);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(6);
assertTrue(rule1.match(rule2));
}
}
This diff is collapsed.
package net.floodlightcontroller.accesscontrollist.test;
import static org.junit.Assert.*;
import java.util.HashSet;
import java.util.Set;
import net.floodlightcontroller.accesscontrollist.ap.AP;
import net.floodlightcontroller.accesscontrollist.ap.APManager;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
public class APManagerTest extends FloodlightTestCase {
@Test
public void testGetDpidSet(){
AP ap1 = new AP("10.0.0.1","00:00:00:00:00:00:00:01");
AP ap2 = new AP("10.0.0.2","00:00:00:00:00:00:00:02");
AP ap3 = new AP("10.0.0.3","00:00:00:00:00:00:00:03");
APManager apManager = new APManager();
apManager.addAP(ap1);
apManager.addAP(ap2);
apManager.addAP(ap3);
int cidr[];
// test CIDR IP with suffix that equals "/32"
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
Set<String> resultSet = apManager.getDpidSet(cidr[0],cidr[1]);
Set<String> expectedSet = new HashSet<String>();
expectedSet.add("00:00:00:00:00:00:00:01");
assertEquals(resultSet, expectedSet);
// test CIDR IP with suffix that does not equal "/32"
cidr = IPAddressUtil.parseCIDR("10.0.0.1/30");
resultSet = apManager.getDpidSet(cidr[0],cidr[1]);
expectedSet = new HashSet<String>();
expectedSet.add("00:00:00:00:00:00:00:01");
expectedSet.add("00:00:00:00:00:00:00:02");
expectedSet.add("00:00:00:00:00:00:00:03");
assertEquals(resultSet, expectedSet);
// test CIDR IP does not exist in the network
cidr = IPAddressUtil.parseCIDR("10.0.0.4/32");
resultSet = apManager.getDpidSet(cidr[0],cidr[1]);
expectedSet = new HashSet<String>();
assertEquals(resultSet, expectedSet);
}
}
package net.floodlightcontroller.accesscontrollist.test;
import static org.junit.Assert.*;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
public class IPAddressUtilTest extends FloodlightTestCase {
@Test
public void testParseCIDR(){
String cidr = "10.0.0.1/32";
int[] resultArray = IPAddressUtil.parseCIDR(cidr);
assertEquals(resultArray[0],IPv4.toIPv4Address("10.0.0.1"));
assertEquals(resultArray[1],32);
}
@Test
public void testContainIP(){
int[] cidr = IPAddressUtil.parseCIDR("10.0.0.0/8");
int ip = IPv4.toIPv4Address("10.0.0.1");
assertTrue(IPAddressUtil.containIP(cidr[0], cidr[1], ip));
}
@Test
public void testIsSubnet(){
assertFalse(IPAddressUtil.isSubnet("10.0.0.1/32", "10.0.0.2/32"));
assertTrue(IPAddressUtil.isSubnet("10.0.0.1/8", "10.0.0.2/8"));
assertTrue(IPAddressUtil.isSubnet("10.0.0.1/32", "10.0.0.2/8"));
assertFalse(IPAddressUtil.isSubnet("10.0.0.1/8", "10.0.0.2/32"));
assertTrue(IPAddressUtil.isSubnet("10.0.0.1/8", null));
assertFalse(IPAddressUtil.isSubnet(null, "10.0.0.2/32"));
}
}
package net.floodlightcontroller.accesscontrollist.util;
import net.floodlightcontroller.packet.IPv4;
public class IPAddressUtil {
/**
* parse the given CIDR IP
*
* @return an array contains the CIDR prefix and mask bits
*
*/
public static int[] parseCIDR(String cidr) {
int ret[] = new int[2];
String[] parts = cidr.split("/");
if (parts.length == 1){
throw new IllegalArgumentException("CIDR mask bits must be specified.");
}
String cidrPrefix = parts[0].trim();
int cidrMaskBits = 0;
if (parts.length == 2) {
try {
cidrMaskBits = Integer.parseInt(parts[1].trim());
} catch (Exception e) {
throw new NumberFormatException("CIDR mask bits must be specified as a number(0 ~ 32).");
}
if (cidrMaskBits < 0 || cidrMaskBits > 32) {
throw new NumberFormatException("CIDR mask bits must be 0 <= value <= 32.");
}
}
ret[0] = IPv4.toIPv4Address(cidrPrefix);
ret[1] = cidrMaskBits;
return ret;
}
/**
* check whether the CIDR address contains the IP address
*/
public static boolean containIP(int cidrPrefix, int cidrMaskBits, int ip) {
boolean matched = true;
int bitsToShift = 32 - cidrMaskBits;
if (bitsToShift > 0) {
cidrPrefix = cidrPrefix >> bitsToShift;
ip = ip >> bitsToShift;
cidrPrefix = cidrPrefix << bitsToShift;
ip = ip << bitsToShift;
}
if (cidrPrefix != ip) {
matched = false;
}
return matched;
}
/**
* check whether cidr1 is a subnet of (or the same as) cidr2
*
*/
public static boolean isSubnet(String cidr1, String cidr2) {
if (cidr2 == null) {
return true;
} else if (cidr1 == null) {
return false;
}
int[] cidr = IPAddressUtil.parseCIDR(cidr1);
int cidr1Prefix = cidr[0];
int cidr1MaskBits = cidr[1];
cidr = IPAddressUtil.parseCIDR(cidr2);
int cidr2Prefix = cidr[0];
int cidr2MaskBits = cidr[1];
int bitsToShift_1 = 32 - cidr1MaskBits;
int bitsToShift_2 = 32 - cidr2MaskBits;
int offset = (bitsToShift_1 > bitsToShift_2) ? bitsToShift_1
: bitsToShift_2;
if (offset > 0) {
cidr1Prefix = cidr1Prefix >> offset;
cidr2Prefix = cidr2Prefix >> offset;
cidr1Prefix = cidr1Prefix << offset;
cidr2Prefix = cidr2Prefix << offset;
}
if (cidr1Prefix == cidr2Prefix) {
if (cidr1MaskBits >= cidr2MaskBits) {
return true;
}
}
return false;
}
}
package net.floodlightcontroller.accesscontrollist.web;
import java.io.IOException;
import java.util.Iterator;
import net.floodlightcontroller.accesscontrollist.ACLRule;
import net.floodlightcontroller.accesscontrollist.IACLService;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.MappingJsonFactory;
public class ACLRuleResource extends ServerResource {
protected static Logger log = LoggerFactory
.getLogger(ACLRuleResource.class);
@Get("json")
public Object handleRequest() {
IACLService acl = (IACLService) getContext().getAttributes().get(
IACLService.class.getCanonicalName());
return acl.getRules();
}
/**
* parse a JSON string into a ACL rule instance, then add it to the ACL
* @return A string status message
*/
@Post
public String store(String json) {
IACLService aclService = (IACLService) getContext().getAttributes().get(
IACLService.class.getCanonicalName());
ACLRule newRule;
try {
newRule = jsonToRule(json);
} catch (Exception e) {
log.error("Error parsing ACL rule: " + json, e);
return "{\"status\" : \"Failed! " + e.getMessage() + "\"}";
}
String status = null;
String nw_src = newRule.getNw_src();
String nw_dst = newRule.getNw_dst();
if (nw_src == null && nw_dst == null){
status = "Failed! Either nw_src or nw_dst must be specified.";
return ("{\"status\" : \"" + status + "\"}");
}
if(aclService.addRule(newRule)){
status = "Success! New rule added.";
}else{
status = "Failed! The new ACL rule matches an existing rule.";
}
return ("{\"status\" : \"" + status + "\"}");
}
/**
* parse a JSON string into a ACL rule instance, then remove it from the ACL
* @return A string status message
*/
@Delete
public String remove(String json) {
IACLService ACL = (IACLService) getContext().getAttributes().get(
IACLService.class.getCanonicalName());
ACLRule rule;
try {
rule = jsonToRule(json);
} catch (Exception e) {
log.error("Error parsing ACL rule: " + json, e);
return "{\"status\" : \"Failed! " + e.getMessage() + "\"}";
}
// check whether the rule exists
boolean exists = false;
Iterator<ACLRule> iter = ACL.getRules().iterator();
while (iter.hasNext()) {
ACLRule r = iter.next();
if (r.getId() == rule.getId()) {
exists = true;
break;
}
}
String status = null;
if (!exists) {
status = "Failed! a rule with this ID doesn't exist.";
log.error(status);
} else {
ACL.removeRule(rule.getId());
status = "Success! Rule deleted";
}
return ("{\"status\" : \"" + status + "\"}");
}
/**
* Turns a JSON string into a ACL rule instance
*/
public static ACLRule jsonToRule(String json) throws IOException {
ACLRule rule = new ACLRule();
MappingJsonFactory f = new MappingJsonFactory();
JsonParser jp;
try {
jp = f.createJsonParser(json);
} catch (JsonParseException e) {
throw new IOException(e);
}
jp.nextToken();
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw new IOException("Expected START_OBJECT");
}
while (jp.nextToken() != JsonToken.END_OBJECT) {
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
throw new IOException("Expected FIELD_NAME");
}
String key = jp.getCurrentName();
jp.nextToken();
String value = jp.getText();
if (value.equals(""))
continue;
// used for removing rule
if ("ruleid".equals(key)) {
try{
rule.setId(Integer.parseInt(value));
} catch(NumberFormatException e){
throw new NumberFormatException("ruleid must be specified as a number.");
}
}
else if ("src-ip".equals(key)) {
rule.setNw_src(value);
int[] cidr = IPAddressUtil.parseCIDR(value);
rule.setNw_src_prefix(cidr[0]);
rule.setNw_src_maskbits(cidr[1]);
}
else if ("dst-ip".equals(key)) {
rule.setNw_dst(value);
int[] cidr = IPAddressUtil.parseCIDR(value);
rule.setNw_dst_prefix(cidr[0]);
rule.setNw_dst_maskbits(cidr[1]);
}
else if ("nw-proto".equals(key)) {
if ("TCP".equalsIgnoreCase(value)) {
rule.setNw_proto(6);
} else if ("UDP".equalsIgnoreCase(value)) {
rule.setNw_proto(11);
} else if ("ICMP".equalsIgnoreCase(value)) {
rule.setNw_proto(1);
} else {
throw new IllegalArgumentException("nw-proto must be specified as (TCP || UDP || ICMP).");
}
}
else if ("tp-dst".equals(key)) {
// only when tp-dst == (TCP || UDP), tp-dst can have non-0 value
if(rule.getNw_proto() == 6 || rule.getNw_proto() == 11){
try{
rule.setTp_dst(Integer.parseInt(value));
}catch(NumberFormatException e){
throw new NumberFormatException("tp-dst must be specified as a number.");
}
}
}
else if (key == "action") {
if ("allow".equalsIgnoreCase(value)) {
rule.setAction(ACLRule.Action.ALLOW);
} else if ("deny".equalsIgnoreCase(value)) {
rule.setAction(ACLRule.Action.DENY);
} else{
throw new IllegalArgumentException("action must be specidied as (allow || deny).");
}
}
}
return rule;
}
}
package net.floodlightcontroller.accesscontrollist.web;
import net.floodlightcontroller.restserver.RestletRoutable;
import org.restlet.Context;
import org.restlet.Restlet;
import org.restlet.routing.Router;
public class ACLWebRoutable implements RestletRoutable {
/**
* Create the Restlet router and bind to the proper resources.
*/
@Override
public Restlet getRestlet(Context context) {
Router router = new Router(context);
router.attach("/rules/json", ACLRuleResource.class);
router.attach("/clear/json", ClearACRulesResource.class);
return router;
}
/**
* Set the base path for the ACL
*/
@Override
public String basePath() {
return "/wm/acl";
}
}
package net.floodlightcontroller.accesscontrollist.web;
import net.floodlightcontroller.accesscontrollist.IACLService;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ClearACRulesResource extends ServerResource {
protected static Logger log = LoggerFactory
.getLogger(ClearACRulesResource.class);
@Get
public void ClearACRules() {
IACLService acl = (IACLService) getContext().getAttributes().get(
IACLService.class.getCanonicalName());
acl.removeAllRules();
}
}
package net.floodlightcontroller.accesscontrollist;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import net.floodlightcontroller.accesscontrollist.ACL;
import net.floodlightcontroller.accesscontrollist.ACLRule;
import net.floodlightcontroller.accesscontrollist.IACLService;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.accesscontrollist.web.ACLRuleResource;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
import org.restlet.Context;
public class ACLRuleResourceTest extends FloodlightTestCase {
@Test
public void testJsonToRule(){
// check that all the key-value pairs are specified
String json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
try {
ACLRule rule = ACLRuleResource.jsonToRule(json);
assertEquals(rule.getNw_src(),"10.0.0.1/32");
assertEquals(rule.getNw_dst(),"10.0.0.2/32");
int[] cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
assertEquals(rule.getNw_src_prefix(), cidr[0]);
assertEquals(rule.getNw_src_maskbits(), cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
assertEquals(rule.getNw_dst_prefix(), cidr[0]);
assertEquals(rule.getNw_dst_maskbits(), cidr[1]);
assertEquals(rule.getNw_proto(),6);
assertEquals(rule.getTp_dst(), 80);
} catch (IOException e) {
e.printStackTrace();
}
// check that nw_proto is not specified correctly
json = "{\"nw-prot\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
try {
ACLRule rule = ACLRuleResource.jsonToRule(json);
assertEquals(rule.getNw_src(),"10.0.0.1/32");
assertEquals(rule.getNw_dst(),"10.0.0.2/32");
int[] cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
assertEquals(rule.getNw_src_prefix(), cidr[0]);
assertEquals(rule.getNw_src_maskbits(), cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
assertEquals(rule.getNw_dst_prefix(), cidr[0]);
assertEquals(rule.getNw_dst_maskbits(), cidr[1]);
assertEquals(rule.getNw_proto(),0);
assertEquals(rule.getTp_dst(), 0);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testStore(){
ACL s = new ACL();
FloodlightModuleContext fmc = new FloodlightModuleContext();
try {
s.init(fmc);
} catch (FloodlightModuleException e) {
e.printStackTrace();
}
ACLRuleResource r = new ACLRuleResource();
Context ctx = new Context();
r.init(ctx, null, null);
r.getContext().getAttributes().putIfAbsent(IACLService.class.getCanonicalName(), s);
// input a valid JSON string that adds a new ACL rule
String json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Success! New rule added." + "\"}");
// input a valid JSON string that matches an existing rule
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! The new ACL rule matches an existing rule." + "\"}");
// input a valid JSON string that adds a new ACL rule
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/8\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Success! New rule added." + "\"}");
// input a valid JSON string that matches an existing rule
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.2/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! The new ACL rule matches an existing rule." + "\"}");
// input a invalid JSON string that contains neither nw_src and nw_dst
json = "{\"nw-proto\":\"TCP\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! Either nw_src or nw_dst must be specified." + "\"}");
// input a invalid JSON string that doesn't contain CIDR mask bits
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! " + "CIDR mask bits must be specified." + "\"}");
// input a invalid JSON string that contains a invalid IP address
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.256/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! Octet values in specified IPv4 address must be 0 <= value <= 255" + "\"}");
// input a invalid JSON string that contains a invalid IP address
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.01/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! Specified IPv4 address mustcontain 4 sets of numerical digits separated by periods" + "\"}");
// input a invalid JSON string that contains a invalid CIDR mask bits
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/a\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! CIDR mask bits must be specified as a number(0 ~ 32)." + "\"}");
// input a invalid JSON string that contains a invalid CIDR mask bits
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/33\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! CIDR mask bits must be 0 <= value <= 32." + "\"}");
// input a invalid JSON string that contains a invalid nw-proto value
json = "{\"nw-proto\":\"ARP\",\"src-ip\":\"10.0.0.1/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! nw-proto must be specified as (TCP || UDP || ICMP)." + "\"}");
// input a invalid JSON string that contains a invalid tp-dst value
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"tp-dst\":\"a\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! tp-dst must be specified as a number." + "\"}");
// input a invalid JSON string that contains a invalid action value
json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"tp-dst\":\"80\",\"action\":\"PERMIT\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Failed! action must be specidied as (allow || deny)." + "\"}");
}
@Test
public void testRemove(){
ACL s = new ACL();
FloodlightModuleContext fmc = new FloodlightModuleContext();
try {
s.init(fmc);
} catch (FloodlightModuleException e) {
e.printStackTrace();
}
ACLRuleResource r = new ACLRuleResource();
Context ctx = new Context();
r.init(ctx, null, null);
r.getContext().getAttributes().putIfAbsent(IACLService.class.getCanonicalName(), s);
// input a valid JSON string
String json = "{\"nw-proto\":\"TCP\",\"src-ip\":\"10.0.0.1/32\",\"dst-ip\": \"10.0.0.2/32\",\"tp-dst\":\"80\",\"action\":\"ALLOW\"}";
assertEquals(r.store(json),"{\"status\" : \"" + "Success! New rule added." + "\"}");
// input a invalid JSON string that contains a invalid ruleid value
json = "{\"ruleid\":\"a\"}";
assertEquals(r.remove(json),"{\"status\" : \"" + "Failed! ruleid must be specified as a number." + "\"}");
// input a invalid JSON string that contains a non-existing ruleid value
json = "{\"ruleid\":\"2\"}";
assertEquals(r.remove(json),"{\"status\" : \"" + "Failed! a rule with this ID doesn't exist." + "\"}");
// input a valid JSON string that removes an existing ACL rule
json = "{\"ruleid\":\"1\"}";
assertEquals(r.remove(json),"{\"status\" : \"" + "Success! Rule deleted" + "\"}");
}
}
package net.floodlightcontroller.accesscontrollist;
import static org.junit.Assert.*;
import net.floodlightcontroller.accesscontrollist.ACLRule;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
public class ACLRuleTest extends FloodlightTestCase{
@Test
public void testMatch(){
int[] cidr = new int[2];
ACLRule rule1, rule2;
// rule1 & rule2 are the same
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule1.setTp_dst(80);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(6);
rule2.setTp_dst(80);
assertTrue(rule1.match(rule2));
// rule1 & rule2 are different in nw_proto
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(11);
assertFalse(rule1.match(rule2));
// rule1's nw_src is a subnet of rule2's nw_src
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(1);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/8");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(1);
assertTrue(rule1.match(rule2));
// rule1's nw_dst is a subnet of rule2's nw_dst
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(1);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/8");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(1);
assertTrue(rule1.match(rule2));
// rule1's nw_src is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
assertTrue(rule1.match(rule2));
// rule1's nw_dst is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
assertTrue(rule1.match(rule2));
// rule1's nw_proto is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
assertTrue(rule1.match(rule2));
// rule1's tp_dst is specified while rule2's is not
rule1 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule1.setNw_src_prefix(cidr[0]);
rule1.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule1.setNw_dst_prefix(cidr[0]);
rule1.setNw_dst_maskbits(cidr[1]);
rule1.setNw_proto(6);
rule1.setTp_dst(80);
rule2 = new ACLRule();
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
rule2.setNw_src_prefix(cidr[0]);
rule2.setNw_src_maskbits(cidr[1]);
cidr = IPAddressUtil.parseCIDR("10.0.0.2/32");
rule2.setNw_dst_prefix(cidr[0]);
rule2.setNw_dst_maskbits(cidr[1]);
rule2.setNw_proto(6);
assertTrue(rule1.match(rule2));
}
}
This diff is collapsed.
package net.floodlightcontroller.accesscontrollist;
import static org.junit.Assert.*;
import java.util.HashSet;
import java.util.Set;
import net.floodlightcontroller.accesscontrollist.ap.AP;
import net.floodlightcontroller.accesscontrollist.ap.APManager;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
public class APManagerTest extends FloodlightTestCase {
@Test
public void testGetDpidSet(){
AP ap1 = new AP("10.0.0.1","00:00:00:00:00:00:00:01");
AP ap2 = new AP("10.0.0.2","00:00:00:00:00:00:00:02");
AP ap3 = new AP("10.0.0.3","00:00:00:00:00:00:00:03");
APManager apManager = new APManager();
apManager.addAP(ap1);
apManager.addAP(ap2);
apManager.addAP(ap3);
int cidr[];
// test CIDR IP with suffix that equals "/32"
cidr = IPAddressUtil.parseCIDR("10.0.0.1/32");
Set<String> resultSet = apManager.getDpidSet(cidr[0],cidr[1]);
Set<String> expectedSet = new HashSet<String>();
expectedSet.add("00:00:00:00:00:00:00:01");
assertEquals(resultSet, expectedSet);
// test CIDR IP with suffix that does not equal "/32"
cidr = IPAddressUtil.parseCIDR("10.0.0.1/30");
resultSet = apManager.getDpidSet(cidr[0],cidr[1]);
expectedSet = new HashSet<String>();
expectedSet.add("00:00:00:00:00:00:00:01");
expectedSet.add("00:00:00:00:00:00:00:02");
expectedSet.add("00:00:00:00:00:00:00:03");
assertEquals(resultSet, expectedSet);
// test CIDR IP does not exist in the network
cidr = IPAddressUtil.parseCIDR("10.0.0.4/32");
resultSet = apManager.getDpidSet(cidr[0],cidr[1]);
expectedSet = new HashSet<String>();
assertEquals(resultSet, expectedSet);
}
}
package net.floodlightcontroller.accesscontrollist;
import static org.junit.Assert.*;
import net.floodlightcontroller.accesscontrollist.util.IPAddressUtil;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.test.FloodlightTestCase;
import org.junit.Test;
public class IPAddressUtilTest extends FloodlightTestCase {
@Test
public void testParseCIDR(){
String cidr = "10.0.0.1/32";
int[] resultArray = IPAddressUtil.parseCIDR(cidr);
assertEquals(resultArray[0],IPv4.toIPv4Address("10.0.0.1"));
assertEquals(resultArray[1],32);
}
@Test
public void testContainIP(){
int[] cidr = IPAddressUtil.parseCIDR("10.0.0.0/8");
int ip = IPv4.toIPv4Address("10.0.0.1");
assertTrue(IPAddressUtil.containIP(cidr[0], cidr[1], ip));
}
@Test
public void testIsSubnet(){
assertFalse(IPAddressUtil.isSubnet("10.0.0.1/32", "10.0.0.2/32"));
assertTrue(IPAddressUtil.isSubnet("10.0.0.1/8", "10.0.0.2/8"));
assertTrue(IPAddressUtil.isSubnet("10.0.0.1/32", "10.0.0.2/8"));
assertFalse(IPAddressUtil.isSubnet("10.0.0.1/8", "10.0.0.2/32"));
assertTrue(IPAddressUtil.isSubnet("10.0.0.1/8", null));
assertFalse(IPAddressUtil.isSubnet(null, "10.0.0.2/32"));
}
}
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