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