blob: 4879d19f29651d2f334a63a534356083ed49224d [file] [log] [blame]
Pengfei Lue0c02e22015-07-07 15:41:31 +08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Pengfei Lue0c02e22015-07-07 15:41:31 +08003 * Originally created by Pengfei Lu, Network and Cloud Computing Laboratory, Dalian University of Technology, China
Pengfei Lue53419b2015-08-29 10:11:02 +08004 * Advisers: Keqiu Li, Heng Qi and Haisheng Yu
Pengfei Lue0c02e22015-07-07 15:41:31 +08005 * This work is supported by the State Key Program of National Natural Science of China(Grant No. 61432002)
6 * and Prospective Research Project on Future Networks in Jiangsu Future Networks Innovation Institute.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
Thomas Vachuska9bb32352015-09-25 11:31:22 -070020package org.onosproject.acl.impl;
Pengfei Lue0c02e22015-07-07 15:41:31 +080021
22import com.google.common.collect.Collections2;
Thomas Vachuska9bb32352015-09-25 11:31:22 -070023import org.onosproject.acl.AclRule;
24import org.onosproject.acl.AclStore;
Pengfei Lue0c02e22015-07-07 15:41:31 +080025import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
30import org.apache.felix.scr.annotations.Service;
31import org.onlab.util.KryoNamespace;
Thomas Vachuska9bb32352015-09-25 11:31:22 -070032import org.onosproject.acl.RuleId;
Pengfei Lue0c02e22015-07-07 15:41:31 +080033import org.onosproject.core.ApplicationId;
34import org.onosproject.core.CoreService;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.flow.FlowRule;
37import org.onosproject.store.AbstractStore;
38import org.onosproject.store.serializers.KryoNamespaces;
39import org.onosproject.store.service.ConsistentMap;
40import org.onosproject.store.service.Serializer;
41import org.onosproject.store.service.StorageService;
42import org.onosproject.store.service.Versioned;
43import org.slf4j.Logger;
44
45import java.util.ArrayList;
46import java.util.HashSet;
47import java.util.List;
48import java.util.Set;
49
50import static org.slf4j.LoggerFactory.getLogger;
51
52/**
53 * Implementation of the ACL store service.
54 */
55@Component(immediate = true)
56@Service
57public class DistributedAclStore extends AbstractStore implements AclStore {
58
59 private final Logger log = getLogger(getClass());
60 private final int defaultFlowMaxPriority = 30000;
61
62 private ConsistentMap<RuleId, AclRule> ruleSet;
63 private ConsistentMap<DeviceId, Integer> deviceToPriority;
64 private ConsistentMap<RuleId, Set<DeviceId>> ruleToDevice;
65 private ConsistentMap<RuleId, Set<FlowRule>> ruleToFlow;
66 private ConsistentMap<RuleId, List<RuleId>> denyRuleToAllowRule;
67
68 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected StorageService storageService;
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected CoreService coreService;
72
73 @Activate
74 public void activate() {
75 ApplicationId appId = coreService.getAppId("org.onosproject.acl");
76
77 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
78 .register(KryoNamespaces.API)
79 .register(AclRule.class)
80 .register(AclRule.Action.class)
81 .register(RuleId.class);
82
83 ruleSet = storageService.<RuleId, AclRule>consistentMapBuilder()
84 .withSerializer(Serializer.using(serializer.build()))
85 .withName("acl-rule-set")
86 .withApplicationId(appId)
87 .withPurgeOnUninstall()
88 .build();
89
90 deviceToPriority = storageService.<DeviceId, Integer>consistentMapBuilder()
91 .withSerializer(Serializer.using(serializer.build()))
92 .withName("device-to-priority")
93 .withApplicationId(appId)
94 .withPurgeOnUninstall()
95 .build();
96
97 ruleToFlow = storageService.<RuleId, Set<FlowRule>>consistentMapBuilder()
98 .withSerializer(Serializer.using(serializer.build()))
99 .withName("rule-to-flow")
100 .withApplicationId(appId)
101 .withPurgeOnUninstall()
102 .build();
103
104 denyRuleToAllowRule = storageService.<RuleId, List<RuleId>>consistentMapBuilder()
105 .withSerializer(Serializer.using(serializer.build()))
106 .withName("deny-to-allow")
107 .withApplicationId(appId)
108 .withPurgeOnUninstall()
109 .build();
110
111 ruleToDevice = storageService.<RuleId, Set<DeviceId>>consistentMapBuilder()
112 .withSerializer(Serializer.using(serializer.build()))
113 .withName("rule-to-device")
114 .withApplicationId(appId)
115 .withPurgeOnUninstall()
116 .build();
117
118 log.info("Started");
119 }
120
121 @Deactivate
122 public void deactive() {
123 log.info("Stopped");
124 }
125
126 @Override
127 public List<AclRule> getAclRules() {
128 List<AclRule> aclRules = new ArrayList<>();
129 aclRules.addAll(Collections2.transform(ruleSet.values(), Versioned::value));
130 return aclRules;
131 }
132
133 @Override
134 public void addAclRule(AclRule rule) {
135 ruleSet.putIfAbsent(rule.id(), rule);
136 }
137
138 @Override
139 public AclRule getAclRule(RuleId ruleId) {
140 Versioned<AclRule> rule = ruleSet.get(ruleId);
141 if (rule != null) {
142 return rule.value();
143 } else {
144 return null;
145 }
146 }
147
148 @Override
149 public void removeAclRule(RuleId ruleId) {
150 ruleSet.remove(ruleId);
151 }
152
153 @Override
154 public void clearAcl() {
155 ruleSet.clear();
156 deviceToPriority.clear();
157 ruleToFlow.clear();
158 denyRuleToAllowRule.clear();
159 ruleToDevice.clear();
160 }
161
162 @Override
163 public int getPriorityByDevice(DeviceId deviceId) {
164 return deviceToPriority.compute(deviceId,
165 (id, priority) -> (priority == null) ? defaultFlowMaxPriority : (priority - 1))
166 .value();
167 }
168
169 @Override
170 public Set<FlowRule> getFlowByRule(RuleId ruleId) {
171 Versioned<Set<FlowRule>> flowRuleSet = ruleToFlow.get(ruleId);
172 if (flowRuleSet != null) {
173 return flowRuleSet.value();
174 } else {
175 return null;
176 }
177 }
178
179 @Override
180 public void addRuleToFlowMapping(RuleId ruleId, FlowRule flowRule) {
181 ruleToFlow.computeIf(ruleId,
182 flowRuleSet -> (flowRuleSet == null || !flowRuleSet.contains(flowRule)),
183 (id, flowRuleSet) -> {
184 Set<FlowRule> newSet = new HashSet<>();
185 if (flowRuleSet != null) {
186 newSet.addAll(flowRuleSet);
187 }
188 newSet.add(flowRule);
189 return newSet;
190 });
191 }
192
193 @Override
194 public void removeRuleToFlowMapping(RuleId ruleId) {
195 ruleToFlow.remove(ruleId);
196 }
197
198 @Override
199 public List<RuleId> getAllowingRuleByDenyingRule(RuleId denyingRuleId) {
200 Versioned<List<RuleId>> allowRuleIdSet = denyRuleToAllowRule.get(denyingRuleId);
201 if (allowRuleIdSet != null) {
202 return allowRuleIdSet.value();
203 } else {
204 return null;
205 }
206 }
207
208 @Override
209 public void addDenyToAllowMapping(RuleId denyingRuleId, RuleId allowingRuleId) {
210 denyRuleToAllowRule.computeIf(denyingRuleId,
211 ruleIdList -> (ruleIdList == null || !ruleIdList.contains(allowingRuleId)),
212 (id, ruleIdList) -> {
213 ArrayList<RuleId> newList = new ArrayList<>();
214 if (ruleIdList != null) {
215 newList.addAll(ruleIdList);
216 }
217 newList.add(allowingRuleId);
218 return newList;
219 });
220 }
221
222 @Override
223 public void removeDenyToAllowMapping(RuleId denyingRuleId) {
224 denyRuleToAllowRule.remove(denyingRuleId);
225 }
226
227 @Override
228 public boolean checkIfRuleWorksInDevice(RuleId ruleId, DeviceId deviceId) {
229 return ruleToDevice.containsKey(ruleId) && ruleToDevice.get(ruleId).value().contains(deviceId);
230 }
231
232 @Override
233 public void addRuleToDeviceMapping(RuleId ruleId, DeviceId deviceId) {
234 ruleToDevice.computeIf(ruleId,
235 deviceIdSet -> (deviceIdSet == null || !deviceIdSet.contains(deviceId)),
236 (id, deviceIdSet) -> {
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700237 Set<DeviceId> newSet = new HashSet<>();
Pengfei Lue0c02e22015-07-07 15:41:31 +0800238 if (deviceIdSet != null) {
239 newSet.addAll(deviceIdSet);
240 }
241 newSet.add(deviceId);
242 return newSet;
243 });
244 }
245
246 @Override
247 public void removeRuleToDeviceMapping(RuleId ruleId) {
248 ruleToDevice.remove(ruleId);
249 }
250
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700251}