blob: 0036578a4287e89baa56c5cb3174e8d8809c5068 [file] [log] [blame]
Hyunsun Moon60a10672016-06-12 17:39:12 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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.
15 */
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070016package org.opencord.cordvtn.impl.handler;
Hyunsun Moon60a10672016-06-12 17:39:12 -070017
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20
21import org.apache.felix.scr.annotations.Deactivate;
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070022import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
Hyunsun Moon60a10672016-06-12 17:39:12 -070024import org.onlab.packet.Ethernet;
25import org.onlab.packet.Ip4Address;
26import org.onlab.packet.Ip4Prefix;
27import org.onosproject.net.flow.DefaultFlowRule;
28import org.onosproject.net.flow.DefaultTrafficSelector;
29import org.onosproject.net.flow.DefaultTrafficTreatment;
30import org.onosproject.net.flow.FlowRule;
31import org.onosproject.net.flow.TrafficSelector;
32import org.onosproject.net.flow.TrafficTreatment;
33import org.onosproject.net.flow.instructions.ExtensionTreatment;
34import org.opencord.cordvtn.impl.AbstractInstanceHandler;
35import org.opencord.cordvtn.api.CordVtnNode;
36import org.opencord.cordvtn.api.Instance;
37import org.opencord.cordvtn.api.InstanceHandler;
38import org.onosproject.xosclient.api.VtnService;
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070039import org.opencord.cordvtn.impl.CordVtnNodeManager;
Hyunsun Moon60a10672016-06-12 17:39:12 -070040import org.opencord.cordvtn.impl.CordVtnPipeline;
41
42import java.util.Optional;
43
Hyunsun Moon60a10672016-06-12 17:39:12 -070044import static org.onosproject.xosclient.api.VtnServiceApi.ServiceType.DEFAULT;
45
46/**
47 * Provides network connectivity for default service instances.
48 */
49@Component(immediate = true)
50public class DefaultInstanceHandler extends AbstractInstanceHandler implements InstanceHandler {
51
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070052 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 protected CordVtnPipeline pipeline;
54
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected CordVtnNodeManager nodeManager;
57
Hyunsun Moon60a10672016-06-12 17:39:12 -070058 @Activate
59 protected void activate() {
60 serviceType = Optional.of(DEFAULT);
Hyunsun Moon60a10672016-06-12 17:39:12 -070061 super.activate();
62 }
63
64 @Deactivate
65 protected void deactivate() {
66 super.deactivate();
67 }
68
69 @Override
70 public void instanceDetected(Instance instance) {
71 log.info("Instance is detected {}", instance);
72
73 VtnService service = getVtnService(instance.serviceId());
74 if (service == null) {
75 log.warn("Failed to get VtnService for {}", instance);
76 return;
77 }
78 defaultConnectionRules(instance, service, true);
79 }
80
81 @Override
82 public void instanceRemoved(Instance instance) {
83 log.info("Instance is removed {}", instance);
84
85 VtnService service = getVtnService(instance.serviceId());
86 if (service == null) {
87 log.warn("Failed to get VtnService for {}", instance);
88 return;
89 }
90 defaultConnectionRules(instance, service, false);
91 }
92
93 private void defaultConnectionRules(Instance instance, VtnService service, boolean install) {
94 long vni = service.vni();
95 Ip4Prefix serviceIpRange = service.subnet().getIp4Prefix();
96
97 inPortRule(instance, install);
98 dstIpRule(instance, vni, install);
99 tunnelInRule(instance, vni, install);
100
101 if (install) {
102 directAccessRule(serviceIpRange, serviceIpRange, true);
103 serviceIsolationRule(serviceIpRange, true);
104 } else if (getInstances(service.id()).isEmpty()) {
105 directAccessRule(serviceIpRange, serviceIpRange, false);
106 serviceIsolationRule(serviceIpRange, false);
107 }
108 }
109
110 private void inPortRule(Instance instance, boolean install) {
111 TrafficSelector selector = DefaultTrafficSelector.builder()
112 .matchInPort(instance.portNumber())
113 .matchEthType(Ethernet.TYPE_IPV4)
114 .matchIPSrc(instance.ipAddress().toIpPrefix())
115 .build();
116
117 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Hyunsun Moon3a7bf9e2016-06-22 17:35:35 -0700118 .transition(CordVtnPipeline.TABLE_ACCESS)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700119 .build();
120
Hyunsun Moon60a10672016-06-12 17:39:12 -0700121 FlowRule flowRule = DefaultFlowRule.builder()
122 .fromApp(appId)
123 .withSelector(selector)
124 .withTreatment(treatment)
125 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
126 .forDevice(instance.deviceId())
127 .forTable(CordVtnPipeline.TABLE_IN_PORT)
128 .makePermanent()
129 .build();
130
131 pipeline.processFlowRule(install, flowRule);
132
133 selector = DefaultTrafficSelector.builder()
134 .matchInPort(instance.portNumber())
135 .build();
136
137 treatment = DefaultTrafficTreatment.builder()
138 .transition(CordVtnPipeline.TABLE_IN_SERVICE)
139 .build();
140
141 flowRule = DefaultFlowRule.builder()
142 .fromApp(appId)
143 .withSelector(selector)
144 .withTreatment(treatment)
145 .withPriority(CordVtnPipeline.PRIORITY_LOW)
146 .forDevice(instance.deviceId())
147 .forTable(CordVtnPipeline.TABLE_IN_PORT)
148 .makePermanent()
149 .build();
150
151 pipeline.processFlowRule(install, flowRule);
152 }
153
154 private void dstIpRule(Instance instance, long vni, boolean install) {
Hyunsun Moon3ef52492016-06-15 14:56:31 -0700155 Ip4Address tunnelIp = nodeManager.dataIp(instance.deviceId()).getIp4Address();
Hyunsun Moon60a10672016-06-12 17:39:12 -0700156
157 TrafficSelector selector = DefaultTrafficSelector.builder()
158 .matchEthType(Ethernet.TYPE_IPV4)
159 .matchIPDst(instance.ipAddress().toIpPrefix())
160 .build();
161
162 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
163 .setEthDst(instance.mac())
164 .setOutput(instance.portNumber())
165 .build();
166
167 FlowRule flowRule = DefaultFlowRule.builder()
168 .fromApp(appId)
169 .withSelector(selector)
170 .withTreatment(treatment)
171 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
172 .forDevice(instance.deviceId())
Hyunsun Moon3a7bf9e2016-06-22 17:35:35 -0700173 .forTable(CordVtnPipeline.TABLE_DST)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700174 .makePermanent()
175 .build();
176
177 pipeline.processFlowRule(install, flowRule);
178
179 for (CordVtnNode node : nodeManager.completeNodes()) {
Hyunsun Moon3ef52492016-06-15 14:56:31 -0700180 if (node.integrationBridgeId().equals(instance.deviceId())) {
Hyunsun Moon60a10672016-06-12 17:39:12 -0700181 continue;
182 }
183
Hyunsun Moon3ef52492016-06-15 14:56:31 -0700184 ExtensionTreatment tunnelDst =
185 pipeline.tunnelDstTreatment(node.integrationBridgeId(), tunnelIp);
Hyunsun Moon60a10672016-06-12 17:39:12 -0700186 if (tunnelDst == null) {
187 continue;
188 }
189
190 treatment = DefaultTrafficTreatment.builder()
191 .setEthDst(instance.mac())
192 .setTunnelId(vni)
Hyunsun Moon3ef52492016-06-15 14:56:31 -0700193 .extension(tunnelDst, node.integrationBridgeId())
194 .setOutput(nodeManager.tunnelPort(node.integrationBridgeId()))
Hyunsun Moon60a10672016-06-12 17:39:12 -0700195 .build();
196
197 flowRule = DefaultFlowRule.builder()
198 .fromApp(appId)
199 .withSelector(selector)
200 .withTreatment(treatment)
201 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
Hyunsun Moon3ef52492016-06-15 14:56:31 -0700202 .forDevice(node.integrationBridgeId())
Hyunsun Moon3a7bf9e2016-06-22 17:35:35 -0700203 .forTable(CordVtnPipeline.TABLE_DST)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700204 .makePermanent()
205 .build();
206
207 pipeline.processFlowRule(install, flowRule);
208 }
209 }
210
211 private void tunnelInRule(Instance instance, long vni, boolean install) {
212 TrafficSelector selector = DefaultTrafficSelector.builder()
213 .matchTunnelId(vni)
214 .matchEthDst(instance.mac())
215 .build();
216
217 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
218 .setOutput(instance.portNumber())
219 .build();
220
221 FlowRule flowRule = DefaultFlowRule.builder()
222 .fromApp(appId)
223 .withSelector(selector)
224 .withTreatment(treatment)
225 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
226 .forDevice(instance.deviceId())
227 .forTable(CordVtnPipeline.TABLE_TUNNEL_IN)
228 .makePermanent()
229 .build();
230
231 pipeline.processFlowRule(install, flowRule);
232 }
233
234 private void directAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange, boolean install) {
235 TrafficSelector selector = DefaultTrafficSelector.builder()
236 .matchEthType(Ethernet.TYPE_IPV4)
237 .matchIPSrc(srcRange)
238 .matchIPDst(dstRange)
239 .build();
240
241 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Hyunsun Moon3a7bf9e2016-06-22 17:35:35 -0700242 .transition(CordVtnPipeline.TABLE_DST)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700243 .build();
244
245
246 nodeManager.completeNodes().stream().forEach(node -> {
247 FlowRule flowRuleDirect = DefaultFlowRule.builder()
248 .fromApp(appId)
249 .withSelector(selector)
250 .withTreatment(treatment)
251 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
Hyunsun Moon3ef52492016-06-15 14:56:31 -0700252 .forDevice(node.integrationBridgeId())
Hyunsun Moon3a7bf9e2016-06-22 17:35:35 -0700253 .forTable(CordVtnPipeline.TABLE_ACCESS)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700254 .makePermanent()
255 .build();
256
257 pipeline.processFlowRule(install, flowRuleDirect);
258 });
259 }
260
261 private void serviceIsolationRule(Ip4Prefix dstRange, boolean install) {
262 TrafficSelector selector = DefaultTrafficSelector.builder()
263 .matchEthType(Ethernet.TYPE_IPV4)
264 .matchIPDst(dstRange)
265 .build();
266
267 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
268 .drop()
269 .build();
270
271 nodeManager.completeNodes().stream().forEach(node -> {
272 FlowRule flowRuleDirect = DefaultFlowRule.builder()
273 .fromApp(appId)
274 .withSelector(selector)
275 .withTreatment(treatment)
276 .withPriority(CordVtnPipeline.PRIORITY_LOW)
Hyunsun Moon3ef52492016-06-15 14:56:31 -0700277 .forDevice(node.integrationBridgeId())
Hyunsun Moon3a7bf9e2016-06-22 17:35:35 -0700278 .forTable(CordVtnPipeline.TABLE_ACCESS)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700279 .makePermanent()
280 .build();
281
282 pipeline.processFlowRule(install, flowRuleDirect);
283 });
284 }
285}