blob: ce3de312c8d2ef0829aafae48f62928d401b2f09 [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
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070018import com.google.common.collect.ImmutableSet;
Hyunsun Moon60a10672016-06-12 17:39:12 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21
22import org.apache.felix.scr.annotations.Deactivate;
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070023import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
Hyunsun Moon60a10672016-06-12 17:39:12 -070025import org.onlab.packet.Ethernet;
26import org.onlab.packet.Ip4Address;
27import org.onlab.packet.Ip4Prefix;
28import org.onosproject.net.flow.DefaultFlowRule;
29import org.onosproject.net.flow.DefaultTrafficSelector;
30import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.FlowRule;
32import org.onosproject.net.flow.TrafficSelector;
33import org.onosproject.net.flow.TrafficTreatment;
34import org.onosproject.net.flow.instructions.ExtensionTreatment;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070035import org.opencord.cordvtn.api.VtnNetwork;
Hyunsun Moon60a10672016-06-12 17:39:12 -070036import org.opencord.cordvtn.api.CordVtnNode;
37import org.opencord.cordvtn.api.Instance;
38import org.opencord.cordvtn.api.InstanceHandler;
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
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070042import static org.opencord.cordvtn.api.ServiceNetwork.ServiceNetworkType.PRIVATE;
43import static org.opencord.cordvtn.api.ServiceNetwork.ServiceNetworkType.PUBLIC;
Hyunsun Moon60a10672016-06-12 17:39:12 -070044
45/**
46 * Provides network connectivity for default service instances.
47 */
48@Component(immediate = true)
49public class DefaultInstanceHandler extends AbstractInstanceHandler implements InstanceHandler {
50
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070051 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected CordVtnPipeline pipeline;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 protected CordVtnNodeManager nodeManager;
56
Hyunsun Moon60a10672016-06-12 17:39:12 -070057 @Activate
58 protected void activate() {
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070059 netTypes = ImmutableSet.of(PRIVATE, PUBLIC);
Hyunsun Moon60a10672016-06-12 17:39:12 -070060 super.activate();
61 }
62
63 @Deactivate
64 protected void deactivate() {
65 super.deactivate();
66 }
67
68 @Override
69 public void instanceDetected(Instance instance) {
70 log.info("Instance is detected {}", instance);
71
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070072 VtnNetwork vtnNet = getVtnNetwork(instance);
73 populateDefaultRules(instance, vtnNet, true);
Hyunsun Moon60a10672016-06-12 17:39:12 -070074 }
75
76 @Override
77 public void instanceRemoved(Instance instance) {
78 log.info("Instance is removed {}", instance);
79
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070080 VtnNetwork vtnNet = getVtnNetwork(instance);
81 populateDefaultRules(instance, vtnNet, false);
Hyunsun Moon60a10672016-06-12 17:39:12 -070082 }
83
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070084 private void populateDefaultRules(Instance instance, VtnNetwork vtnNet, boolean install) {
85 long vni = vtnNet.segmentId().id();
86 Ip4Prefix serviceIpRange = vtnNet.subnet().getIp4Prefix();
Hyunsun Moon60a10672016-06-12 17:39:12 -070087
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070088 populateInPortRule(instance, install);
89 populateDstIpRule(instance, vni, install);
90 populateTunnelInRule(instance, vni, install);
Hyunsun Moon60a10672016-06-12 17:39:12 -070091
92 if (install) {
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070093 populateDirectAccessRule(serviceIpRange, serviceIpRange, true);
94 populateServiceIsolationRule(serviceIpRange, true);
95 } else if (getInstances(vtnNet.id()).isEmpty()) {
96 populateDirectAccessRule(serviceIpRange, serviceIpRange, false);
97 populateServiceIsolationRule(serviceIpRange, false);
Hyunsun Moon60a10672016-06-12 17:39:12 -070098 }
99 }
100
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700101 private void populateInPortRule(Instance instance, boolean install) {
Hyunsun Moon60a10672016-06-12 17:39:12 -0700102 TrafficSelector selector = DefaultTrafficSelector.builder()
103 .matchInPort(instance.portNumber())
104 .matchEthType(Ethernet.TYPE_IPV4)
105 .matchIPSrc(instance.ipAddress().toIpPrefix())
106 .build();
107
108 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Hyunsun Moon1e88fef2016-08-04 14:00:35 -0700109 .transition(CordVtnPipeline.TABLE_ACCESS)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700110 .build();
111
Hyunsun Moon60a10672016-06-12 17:39:12 -0700112 FlowRule flowRule = DefaultFlowRule.builder()
113 .fromApp(appId)
114 .withSelector(selector)
115 .withTreatment(treatment)
116 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
117 .forDevice(instance.deviceId())
118 .forTable(CordVtnPipeline.TABLE_IN_PORT)
119 .makePermanent()
120 .build();
121
122 pipeline.processFlowRule(install, flowRule);
123
124 selector = DefaultTrafficSelector.builder()
125 .matchInPort(instance.portNumber())
126 .build();
127
128 treatment = DefaultTrafficTreatment.builder()
129 .transition(CordVtnPipeline.TABLE_IN_SERVICE)
130 .build();
131
132 flowRule = DefaultFlowRule.builder()
133 .fromApp(appId)
134 .withSelector(selector)
135 .withTreatment(treatment)
136 .withPriority(CordVtnPipeline.PRIORITY_LOW)
137 .forDevice(instance.deviceId())
138 .forTable(CordVtnPipeline.TABLE_IN_PORT)
139 .makePermanent()
140 .build();
141
142 pipeline.processFlowRule(install, flowRule);
143 }
144
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700145 private void populateDstIpRule(Instance instance, long vni, boolean install) {
Hyunsun Moon81a13562016-08-04 13:48:08 -0700146 Ip4Address tunnelIp = nodeManager.dataIp(instance.deviceId()).getIp4Address();
Hyunsun Moon60a10672016-06-12 17:39:12 -0700147
148 TrafficSelector selector = DefaultTrafficSelector.builder()
149 .matchEthType(Ethernet.TYPE_IPV4)
150 .matchIPDst(instance.ipAddress().toIpPrefix())
151 .build();
152
153 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
154 .setEthDst(instance.mac())
155 .setOutput(instance.portNumber())
156 .build();
157
158 FlowRule flowRule = DefaultFlowRule.builder()
159 .fromApp(appId)
160 .withSelector(selector)
161 .withTreatment(treatment)
162 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
163 .forDevice(instance.deviceId())
Hyunsun Moon1e88fef2016-08-04 14:00:35 -0700164 .forTable(CordVtnPipeline.TABLE_DST)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700165 .makePermanent()
166 .build();
167
168 pipeline.processFlowRule(install, flowRule);
169
170 for (CordVtnNode node : nodeManager.completeNodes()) {
Hyunsun Moon81a13562016-08-04 13:48:08 -0700171 if (node.integrationBridgeId().equals(instance.deviceId())) {
Hyunsun Moon60a10672016-06-12 17:39:12 -0700172 continue;
173 }
174
Hyunsun Moon81a13562016-08-04 13:48:08 -0700175 ExtensionTreatment tunnelDst =
176 pipeline.tunnelDstTreatment(node.integrationBridgeId(), tunnelIp);
Hyunsun Moon60a10672016-06-12 17:39:12 -0700177 if (tunnelDst == null) {
178 continue;
179 }
180
181 treatment = DefaultTrafficTreatment.builder()
182 .setEthDst(instance.mac())
183 .setTunnelId(vni)
Hyunsun Moon81a13562016-08-04 13:48:08 -0700184 .extension(tunnelDst, node.integrationBridgeId())
185 .setOutput(nodeManager.tunnelPort(node.integrationBridgeId()))
Hyunsun Moon60a10672016-06-12 17:39:12 -0700186 .build();
187
188 flowRule = DefaultFlowRule.builder()
189 .fromApp(appId)
190 .withSelector(selector)
191 .withTreatment(treatment)
192 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
Hyunsun Moon81a13562016-08-04 13:48:08 -0700193 .forDevice(node.integrationBridgeId())
Hyunsun Moon1e88fef2016-08-04 14:00:35 -0700194 .forTable(CordVtnPipeline.TABLE_DST)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700195 .makePermanent()
196 .build();
197
198 pipeline.processFlowRule(install, flowRule);
199 }
200 }
201
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700202 private void populateTunnelInRule(Instance instance, long vni, boolean install) {
Hyunsun Moon60a10672016-06-12 17:39:12 -0700203 TrafficSelector selector = DefaultTrafficSelector.builder()
204 .matchTunnelId(vni)
205 .matchEthDst(instance.mac())
206 .build();
207
208 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
209 .setOutput(instance.portNumber())
210 .build();
211
212 FlowRule flowRule = DefaultFlowRule.builder()
213 .fromApp(appId)
214 .withSelector(selector)
215 .withTreatment(treatment)
216 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
217 .forDevice(instance.deviceId())
218 .forTable(CordVtnPipeline.TABLE_TUNNEL_IN)
219 .makePermanent()
220 .build();
221
222 pipeline.processFlowRule(install, flowRule);
223 }
224
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700225 private void populateDirectAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange, boolean install) {
Hyunsun Moon60a10672016-06-12 17:39:12 -0700226 TrafficSelector selector = DefaultTrafficSelector.builder()
227 .matchEthType(Ethernet.TYPE_IPV4)
228 .matchIPSrc(srcRange)
229 .matchIPDst(dstRange)
230 .build();
231
232 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Hyunsun Moon1e88fef2016-08-04 14:00:35 -0700233 .transition(CordVtnPipeline.TABLE_DST)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700234 .build();
235
236
237 nodeManager.completeNodes().stream().forEach(node -> {
238 FlowRule flowRuleDirect = DefaultFlowRule.builder()
239 .fromApp(appId)
240 .withSelector(selector)
241 .withTreatment(treatment)
242 .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
Hyunsun Moon81a13562016-08-04 13:48:08 -0700243 .forDevice(node.integrationBridgeId())
Hyunsun Moon1e88fef2016-08-04 14:00:35 -0700244 .forTable(CordVtnPipeline.TABLE_ACCESS)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700245 .makePermanent()
246 .build();
247
248 pipeline.processFlowRule(install, flowRuleDirect);
249 });
250 }
251
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700252 private void populateServiceIsolationRule(Ip4Prefix dstRange, boolean install) {
Hyunsun Moon60a10672016-06-12 17:39:12 -0700253 TrafficSelector selector = DefaultTrafficSelector.builder()
254 .matchEthType(Ethernet.TYPE_IPV4)
255 .matchIPDst(dstRange)
256 .build();
257
258 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
259 .drop()
260 .build();
261
262 nodeManager.completeNodes().stream().forEach(node -> {
263 FlowRule flowRuleDirect = DefaultFlowRule.builder()
264 .fromApp(appId)
265 .withSelector(selector)
266 .withTreatment(treatment)
267 .withPriority(CordVtnPipeline.PRIORITY_LOW)
Hyunsun Moon81a13562016-08-04 13:48:08 -0700268 .forDevice(node.integrationBridgeId())
Hyunsun Moon1e88fef2016-08-04 14:00:35 -0700269 .forTable(CordVtnPipeline.TABLE_ACCESS)
Hyunsun Moon60a10672016-06-12 17:39:12 -0700270 .makePermanent()
271 .build();
272
273 pipeline.processFlowRule(install, flowRuleDirect);
274 });
275 }
276}