diff options
Diffstat (limited to 'framework/src/onos/apps/acl/src/main/java/org/onosproject/acl/impl/DistributedAclStore.java')
-rw-r--r-- | framework/src/onos/apps/acl/src/main/java/org/onosproject/acl/impl/DistributedAclStore.java | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/framework/src/onos/apps/acl/src/main/java/org/onosproject/acl/impl/DistributedAclStore.java b/framework/src/onos/apps/acl/src/main/java/org/onosproject/acl/impl/DistributedAclStore.java new file mode 100644 index 00000000..a5fcfcc7 --- /dev/null +++ b/framework/src/onos/apps/acl/src/main/java/org/onosproject/acl/impl/DistributedAclStore.java @@ -0,0 +1,251 @@ +/* + * Copyright 2015 Open Networking Laboratory + * Originally created by Pengfei Lu, Network and Cloud Computing Laboratory, Dalian University of Technology, China + * Advisers: Keqiu Li, Heng Qi and Haisheng Yu + * This work is supported by the State Key Program of National Natural Science of China(Grant No. 61432002) + * and Prospective Research Project on Future Networks in Jiangsu Future Networks Innovation Institute. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.acl.impl; + +import com.google.common.collect.Collections2; +import org.onosproject.acl.AclRule; +import org.onosproject.acl.AclStore; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.util.KryoNamespace; +import org.onosproject.acl.RuleId; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flow.FlowRule; +import org.onosproject.store.AbstractStore; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.ConsistentMap; +import org.onosproject.store.service.Serializer; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.Versioned; +import org.slf4j.Logger; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Implementation of the ACL store service. + */ +@Component(immediate = true) +@Service +public class DistributedAclStore extends AbstractStore implements AclStore { + + private final Logger log = getLogger(getClass()); + private final int defaultFlowMaxPriority = 30000; + + private ConsistentMap<RuleId, AclRule> ruleSet; + private ConsistentMap<DeviceId, Integer> deviceToPriority; + private ConsistentMap<RuleId, Set<DeviceId>> ruleToDevice; + private ConsistentMap<RuleId, Set<FlowRule>> ruleToFlow; + private ConsistentMap<RuleId, List<RuleId>> denyRuleToAllowRule; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Activate + public void activate() { + ApplicationId appId = coreService.getAppId("org.onosproject.acl"); + + KryoNamespace.Builder serializer = KryoNamespace.newBuilder() + .register(KryoNamespaces.API) + .register(AclRule.class) + .register(AclRule.Action.class) + .register(RuleId.class); + + ruleSet = storageService.<RuleId, AclRule>consistentMapBuilder() + .withSerializer(Serializer.using(serializer.build())) + .withName("acl-rule-set") + .withApplicationId(appId) + .withPurgeOnUninstall() + .build(); + + deviceToPriority = storageService.<DeviceId, Integer>consistentMapBuilder() + .withSerializer(Serializer.using(serializer.build())) + .withName("device-to-priority") + .withApplicationId(appId) + .withPurgeOnUninstall() + .build(); + + ruleToFlow = storageService.<RuleId, Set<FlowRule>>consistentMapBuilder() + .withSerializer(Serializer.using(serializer.build())) + .withName("rule-to-flow") + .withApplicationId(appId) + .withPurgeOnUninstall() + .build(); + + denyRuleToAllowRule = storageService.<RuleId, List<RuleId>>consistentMapBuilder() + .withSerializer(Serializer.using(serializer.build())) + .withName("deny-to-allow") + .withApplicationId(appId) + .withPurgeOnUninstall() + .build(); + + ruleToDevice = storageService.<RuleId, Set<DeviceId>>consistentMapBuilder() + .withSerializer(Serializer.using(serializer.build())) + .withName("rule-to-device") + .withApplicationId(appId) + .withPurgeOnUninstall() + .build(); + + log.info("Started"); + } + + @Deactivate + public void deactive() { + log.info("Stopped"); + } + + @Override + public List<AclRule> getAclRules() { + List<AclRule> aclRules = new ArrayList<>(); + aclRules.addAll(Collections2.transform(ruleSet.values(), Versioned::value)); + return aclRules; + } + + @Override + public void addAclRule(AclRule rule) { + ruleSet.putIfAbsent(rule.id(), rule); + } + + @Override + public AclRule getAclRule(RuleId ruleId) { + Versioned<AclRule> rule = ruleSet.get(ruleId); + if (rule != null) { + return rule.value(); + } else { + return null; + } + } + + @Override + public void removeAclRule(RuleId ruleId) { + ruleSet.remove(ruleId); + } + + @Override + public void clearAcl() { + ruleSet.clear(); + deviceToPriority.clear(); + ruleToFlow.clear(); + denyRuleToAllowRule.clear(); + ruleToDevice.clear(); + } + + @Override + public int getPriorityByDevice(DeviceId deviceId) { + return deviceToPriority.compute(deviceId, + (id, priority) -> (priority == null) ? defaultFlowMaxPriority : (priority - 1)) + .value(); + } + + @Override + public Set<FlowRule> getFlowByRule(RuleId ruleId) { + Versioned<Set<FlowRule>> flowRuleSet = ruleToFlow.get(ruleId); + if (flowRuleSet != null) { + return flowRuleSet.value(); + } else { + return null; + } + } + + @Override + public void addRuleToFlowMapping(RuleId ruleId, FlowRule flowRule) { + ruleToFlow.computeIf(ruleId, + flowRuleSet -> (flowRuleSet == null || !flowRuleSet.contains(flowRule)), + (id, flowRuleSet) -> { + Set<FlowRule> newSet = new HashSet<>(); + if (flowRuleSet != null) { + newSet.addAll(flowRuleSet); + } + newSet.add(flowRule); + return newSet; + }); + } + + @Override + public void removeRuleToFlowMapping(RuleId ruleId) { + ruleToFlow.remove(ruleId); + } + + @Override + public List<RuleId> getAllowingRuleByDenyingRule(RuleId denyingRuleId) { + Versioned<List<RuleId>> allowRuleIdSet = denyRuleToAllowRule.get(denyingRuleId); + if (allowRuleIdSet != null) { + return allowRuleIdSet.value(); + } else { + return null; + } + } + + @Override + public void addDenyToAllowMapping(RuleId denyingRuleId, RuleId allowingRuleId) { + denyRuleToAllowRule.computeIf(denyingRuleId, + ruleIdList -> (ruleIdList == null || !ruleIdList.contains(allowingRuleId)), + (id, ruleIdList) -> { + ArrayList<RuleId> newList = new ArrayList<>(); + if (ruleIdList != null) { + newList.addAll(ruleIdList); + } + newList.add(allowingRuleId); + return newList; + }); + } + + @Override + public void removeDenyToAllowMapping(RuleId denyingRuleId) { + denyRuleToAllowRule.remove(denyingRuleId); + } + + @Override + public boolean checkIfRuleWorksInDevice(RuleId ruleId, DeviceId deviceId) { + return ruleToDevice.containsKey(ruleId) && ruleToDevice.get(ruleId).value().contains(deviceId); + } + + @Override + public void addRuleToDeviceMapping(RuleId ruleId, DeviceId deviceId) { + ruleToDevice.computeIf(ruleId, + deviceIdSet -> (deviceIdSet == null || !deviceIdSet.contains(deviceId)), + (id, deviceIdSet) -> { + Set<DeviceId> newSet = new HashSet<>(); + if (deviceIdSet != null) { + newSet.addAll(deviceIdSet); + } + newSet.add(deviceId); + return newSet; + }); + } + + @Override + public void removeRuleToDeviceMapping(RuleId ruleId) { + ruleToDevice.remove(ruleId); + } + +} |