2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onosproject.segmentrouting;
19 import org.onlab.packet.Ethernet;
20 import org.onlab.packet.IpPrefix;
21 import org.onlab.packet.TpPort;
22 import org.onosproject.cli.net.IpProtocol;
23 import org.onosproject.core.ApplicationId;
24 import org.onosproject.net.DeviceId;
25 import org.onosproject.net.flow.DefaultTrafficSelector;
26 import org.onosproject.net.flow.TrafficSelector;
27 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
28 import org.onosproject.net.flowobjective.FlowObjectiveService;
29 import org.onosproject.net.flowobjective.ForwardingObjective;
30 import org.onosproject.store.service.EventuallyConsistentMap;
31 import org.slf4j.Logger;
33 import java.util.List;
34 import java.util.stream.Collectors;
36 import static org.slf4j.LoggerFactory.getLogger;
39 * Segment Routing Policy Handler.
41 public class PolicyHandler {
43 protected final Logger log = getLogger(getClass());
45 private ApplicationId appId;
46 private DeviceConfiguration deviceConfiguration;
47 private FlowObjectiveService flowObjectiveService;
48 private TunnelHandler tunnelHandler;
49 private final EventuallyConsistentMap<String, Policy> policyStore;
61 * Creates a reference.
63 * @param appId segment routing application ID
64 * @param deviceConfiguration DeviceConfiguration reference
65 * @param flowObjectiveService FlowObjectiveService reference
66 * @param tunnelHandler tunnel handler reference
67 * @param policyStore policy store
69 public PolicyHandler(ApplicationId appId,
70 DeviceConfiguration deviceConfiguration,
71 FlowObjectiveService flowObjectiveService,
72 TunnelHandler tunnelHandler,
73 EventuallyConsistentMap<String, Policy> policyStore) {
75 this.deviceConfiguration = deviceConfiguration;
76 this.flowObjectiveService = flowObjectiveService;
77 this.tunnelHandler = tunnelHandler;
78 this.policyStore = policyStore;
82 * Returns the policies.
86 public List<Policy> getPolicies() {
87 return policyStore.values()
89 .filter(policy -> policy instanceof TunnelPolicy)
90 .map(policy -> new TunnelPolicy((TunnelPolicy) policy))
91 .collect(Collectors.toList());
95 * Creates a policy using the policy information given.
96 * @param policy policy reference to create
97 * @return ID_EXISTS if the same policy ID exists,
98 * POLICY_EXISTS if the same policy exists, TUNNEL_NOT_FOUND if the tunnel
99 * does not exists, UNSUPPORTED_TYPE if the policy type is not supported,
100 * SUCCESS if the policy is created successfully
102 public Result createPolicy(Policy policy) {
104 if (policyStore.containsKey(policy.id())) {
105 log.warn("The policy id {} exists already", policy.id());
106 return Result.ID_EXISTS;
109 if (policyStore.containsValue(policy)) {
110 log.warn("The same policy exists already");
111 return Result.POLICY_EXISTS;
114 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
116 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
117 Tunnel tunnel = tunnelHandler.getTunnel(tunnelPolicy.tunnelId());
118 if (tunnel == null) {
119 return Result.TUNNEL_NOT_FOUND;
122 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
126 .nextStep(tunnel.groupId())
127 .withPriority(tunnelPolicy.priority())
128 .withSelector(buildSelector(policy))
129 .withFlag(ForwardingObjective.Flag.VERSATILE);
131 DeviceId source = deviceConfiguration.getDeviceId(tunnel.labelIds().get(0));
132 flowObjectiveService.forward(source, fwdBuilder.add());
135 log.warn("Policy type {} is not supported yet.", policy.type());
136 return Result.UNSUPPORTED_TYPE;
139 policyStore.put(policy.id(), policy);
141 return Result.SUCCESS;
145 * Removes the policy given.
147 * @param policyInfo policy information to remove
148 * @return POLICY_NOT_FOUND if the policy to remove does not exists,
149 * SUCCESS if it is removed successfully
151 public Result removePolicy(Policy policyInfo) {
153 if (policyStore.get(policyInfo.id()) != null) {
154 Policy policy = policyStore.get(policyInfo.id());
155 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
156 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
157 Tunnel tunnel = tunnelHandler.getTunnel(tunnelPolicy.tunnelId());
159 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
163 .withSelector(buildSelector(policy))
164 .withPriority(tunnelPolicy.priority())
165 .nextStep(tunnel.groupId())
166 .withFlag(ForwardingObjective.Flag.VERSATILE);
168 DeviceId source = deviceConfiguration.getDeviceId(tunnel.labelIds().get(0));
169 flowObjectiveService.forward(source, fwdBuilder.remove());
171 policyStore.remove(policyInfo.id());
174 log.warn("Policy {} was not found", policyInfo.id());
175 return Result.POLICY_NOT_FOUND;
178 return Result.SUCCESS;
182 private TrafficSelector buildSelector(Policy policy) {
184 TrafficSelector.Builder tsb = DefaultTrafficSelector.builder();
185 tsb.matchEthType(Ethernet.TYPE_IPV4);
186 if (policy.dstIp() != null && !policy.dstIp().isEmpty()) {
187 tsb.matchIPDst(IpPrefix.valueOf(policy.dstIp()));
189 if (policy.srcIp() != null && !policy.srcIp().isEmpty()) {
190 tsb.matchIPSrc(IpPrefix.valueOf(policy.srcIp()));
192 if (policy.ipProto() != null && !policy.ipProto().isEmpty()) {
193 Short ipProto = IpProtocol.valueOf(policy.ipProto()).value();
194 tsb.matchIPProtocol(ipProto.byteValue());
195 if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.TCP)) {
196 if (policy.srcPort() != 0) {
197 tsb.matchTcpSrc(TpPort.tpPort(policy.srcPort()));
199 if (policy.dstPort() != 0) {
200 tsb.matchTcpDst(TpPort.tpPort(policy.dstPort()));
202 } else if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.UDP)) {
203 if (policy.srcPort() != 0) {
204 tsb.matchUdpSrc(TpPort.tpPort(policy.srcPort()));
206 if (policy.dstPort() != 0) {
207 tsb.matchUdpDst(TpPort.tpPort(policy.dstPort()));