blob: 0dbb7185caa10578f9cd9e2463f1af7f6046e8f7 [file] [log] [blame]
Pengfei Lue0c02e22015-07-07 15:41:31 +08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
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;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070024import org.onlab.util.KryoNamespace;
Thomas Vachuska9bb32352015-09-25 11:31:22 -070025import org.onosproject.acl.AclRule;
26import org.onosproject.acl.AclStore;
Thomas Vachuska9bb32352015-09-25 11:31:22 -070027import org.onosproject.acl.RuleId;
Pengfei Lue0c02e22015-07-07 15:41:31 +080028import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
30import org.onosproject.net.DeviceId;
31import org.onosproject.net.flow.FlowRule;
32import org.onosproject.store.AbstractStore;
33import org.onosproject.store.serializers.KryoNamespaces;
34import org.onosproject.store.service.ConsistentMap;
35import org.onosproject.store.service.Serializer;
36import org.onosproject.store.service.StorageService;
37import org.onosproject.store.service.Versioned;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070038import org.osgi.service.component.annotations.Activate;
39import org.osgi.service.component.annotations.Component;
40import org.osgi.service.component.annotations.Deactivate;
41import org.osgi.service.component.annotations.Reference;
42import org.osgi.service.component.annotations.ReferenceCardinality;
Pengfei Lue0c02e22015-07-07 15:41:31 +080043import 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 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070055@Component(immediate = true, service = AclStore.class)
Pengfei Lue0c02e22015-07-07 15:41:31 +080056public class DistributedAclStore extends AbstractStore implements AclStore {
57
58 private final Logger log = getLogger(getClass());
59 private final int defaultFlowMaxPriority = 30000;
60
61 private ConsistentMap<RuleId, AclRule> ruleSet;
62 private ConsistentMap<DeviceId, Integer> deviceToPriority;
63 private ConsistentMap<RuleId, Set<DeviceId>> ruleToDevice;
64 private ConsistentMap<RuleId, Set<FlowRule>> ruleToFlow;
65 private ConsistentMap<RuleId, List<RuleId>> denyRuleToAllowRule;
66
Ray Milkeyd84f89b2018-08-17 14:54:17 -070067 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pengfei Lue0c02e22015-07-07 15:41:31 +080068 protected StorageService storageService;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070069 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pengfei Lue0c02e22015-07-07 15:41:31 +080070 protected CoreService coreService;
71
72 @Activate
73 public void activate() {
74 ApplicationId appId = coreService.getAppId("org.onosproject.acl");
75
76 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
77 .register(KryoNamespaces.API)
78 .register(AclRule.class)
79 .register(AclRule.Action.class)
80 .register(RuleId.class);
81
82 ruleSet = storageService.<RuleId, AclRule>consistentMapBuilder()
83 .withSerializer(Serializer.using(serializer.build()))
84 .withName("acl-rule-set")
85 .withApplicationId(appId)
86 .withPurgeOnUninstall()
87 .build();
88
89 deviceToPriority = storageService.<DeviceId, Integer>consistentMapBuilder()
90 .withSerializer(Serializer.using(serializer.build()))
91 .withName("device-to-priority")
92 .withApplicationId(appId)
93 .withPurgeOnUninstall()
94 .build();
95
96 ruleToFlow = storageService.<RuleId, Set<FlowRule>>consistentMapBuilder()
97 .withSerializer(Serializer.using(serializer.build()))
98 .withName("rule-to-flow")
99 .withApplicationId(appId)
100 .withPurgeOnUninstall()
101 .build();
102
103 denyRuleToAllowRule = storageService.<RuleId, List<RuleId>>consistentMapBuilder()
104 .withSerializer(Serializer.using(serializer.build()))
105 .withName("deny-to-allow")
106 .withApplicationId(appId)
107 .withPurgeOnUninstall()
108 .build();
109
110 ruleToDevice = storageService.<RuleId, Set<DeviceId>>consistentMapBuilder()
111 .withSerializer(Serializer.using(serializer.build()))
112 .withName("rule-to-device")
113 .withApplicationId(appId)
114 .withPurgeOnUninstall()
115 .build();
116
117 log.info("Started");
118 }
119
120 @Deactivate
121 public void deactive() {
122 log.info("Stopped");
123 }
124
125 @Override
126 public List<AclRule> getAclRules() {
127 List<AclRule> aclRules = new ArrayList<>();
128 aclRules.addAll(Collections2.transform(ruleSet.values(), Versioned::value));
129 return aclRules;
130 }
131
132 @Override
133 public void addAclRule(AclRule rule) {
134 ruleSet.putIfAbsent(rule.id(), rule);
135 }
136
137 @Override
138 public AclRule getAclRule(RuleId ruleId) {
139 Versioned<AclRule> rule = ruleSet.get(ruleId);
140 if (rule != null) {
141 return rule.value();
142 } else {
143 return null;
144 }
145 }
146
147 @Override
148 public void removeAclRule(RuleId ruleId) {
149 ruleSet.remove(ruleId);
150 }
151
152 @Override
153 public void clearAcl() {
154 ruleSet.clear();
155 deviceToPriority.clear();
156 ruleToFlow.clear();
157 denyRuleToAllowRule.clear();
158 ruleToDevice.clear();
159 }
160
161 @Override
162 public int getPriorityByDevice(DeviceId deviceId) {
163 return deviceToPriority.compute(deviceId,
164 (id, priority) -> (priority == null) ? defaultFlowMaxPriority : (priority - 1))
165 .value();
166 }
167
168 @Override
169 public Set<FlowRule> getFlowByRule(RuleId ruleId) {
170 Versioned<Set<FlowRule>> flowRuleSet = ruleToFlow.get(ruleId);
171 if (flowRuleSet != null) {
172 return flowRuleSet.value();
173 } else {
174 return null;
175 }
176 }
177
178 @Override
179 public void addRuleToFlowMapping(RuleId ruleId, FlowRule flowRule) {
180 ruleToFlow.computeIf(ruleId,
181 flowRuleSet -> (flowRuleSet == null || !flowRuleSet.contains(flowRule)),
182 (id, flowRuleSet) -> {
183 Set<FlowRule> newSet = new HashSet<>();
184 if (flowRuleSet != null) {
185 newSet.addAll(flowRuleSet);
186 }
187 newSet.add(flowRule);
188 return newSet;
189 });
190 }
191
192 @Override
193 public void removeRuleToFlowMapping(RuleId ruleId) {
194 ruleToFlow.remove(ruleId);
195 }
196
197 @Override
198 public List<RuleId> getAllowingRuleByDenyingRule(RuleId denyingRuleId) {
199 Versioned<List<RuleId>> allowRuleIdSet = denyRuleToAllowRule.get(denyingRuleId);
200 if (allowRuleIdSet != null) {
201 return allowRuleIdSet.value();
202 } else {
203 return null;
204 }
205 }
206
207 @Override
208 public void addDenyToAllowMapping(RuleId denyingRuleId, RuleId allowingRuleId) {
209 denyRuleToAllowRule.computeIf(denyingRuleId,
210 ruleIdList -> (ruleIdList == null || !ruleIdList.contains(allowingRuleId)),
211 (id, ruleIdList) -> {
212 ArrayList<RuleId> newList = new ArrayList<>();
213 if (ruleIdList != null) {
214 newList.addAll(ruleIdList);
215 }
216 newList.add(allowingRuleId);
217 return newList;
218 });
219 }
220
221 @Override
222 public void removeDenyToAllowMapping(RuleId denyingRuleId) {
223 denyRuleToAllowRule.remove(denyingRuleId);
224 }
225
226 @Override
227 public boolean checkIfRuleWorksInDevice(RuleId ruleId, DeviceId deviceId) {
228 return ruleToDevice.containsKey(ruleId) && ruleToDevice.get(ruleId).value().contains(deviceId);
229 }
230
231 @Override
232 public void addRuleToDeviceMapping(RuleId ruleId, DeviceId deviceId) {
233 ruleToDevice.computeIf(ruleId,
234 deviceIdSet -> (deviceIdSet == null || !deviceIdSet.contains(deviceId)),
235 (id, deviceIdSet) -> {
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700236 Set<DeviceId> newSet = new HashSet<>();
Pengfei Lue0c02e22015-07-07 15:41:31 +0800237 if (deviceIdSet != null) {
238 newSet.addAll(deviceIdSet);
239 }
240 newSet.add(deviceId);
241 return newSet;
242 });
243 }
244
245 @Override
246 public void removeRuleToDeviceMapping(RuleId ruleId) {
247 ruleToDevice.remove(ruleId);
248 }
249
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700250}