blob: ae6dfad562b3c0660be7cf026f18952935dd8b03 [file] [log] [blame]
Mahesh Poojary S335e7c32015-10-29 10:16:51 +05301/*
2 * Copyright 2015 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 */
16package org.onosproject.sfc.manager.impl;
17
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053018import static org.slf4j.LoggerFactory.getLogger;
19
Phaneendra Mandab3555032016-02-08 11:41:53 +053020import java.util.Collection;
21import java.util.Set;
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053022import java.util.concurrent.ConcurrentHashMap;
23import java.util.concurrent.ConcurrentMap;
24
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053025import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053028import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053030import org.apache.felix.scr.annotations.Service;
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053031import org.onlab.packet.Ethernet;
32import org.onlab.packet.IPv4;
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053033import org.onlab.packet.IpAddress;
34import org.onlab.packet.MacAddress;
Phaneendra Mandab3555032016-02-08 11:41:53 +053035import org.onlab.packet.TCP;
36import org.onlab.packet.UDP;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053037import org.onlab.util.ItemNotFoundException;
Jonathan Hart51539b82015-10-29 09:53:04 -070038import org.onlab.util.KryoNamespace;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053039import org.onosproject.core.ApplicationId;
40import org.onosproject.core.CoreService;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053041import org.onosproject.net.NshServicePathId;
Phaneendra Mandab3555032016-02-08 11:41:53 +053042import org.onosproject.net.PortNumber;
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053043import org.onosproject.net.packet.PacketContext;
44import org.onosproject.net.packet.PacketProcessor;
45import org.onosproject.net.packet.PacketService;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053046import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService;
47import org.onosproject.sfc.forwarder.impl.ServiceFunctionForwarderImpl;
48import org.onosproject.sfc.installer.FlowClassifierInstallerService;
49import org.onosproject.sfc.installer.impl.FlowClassifierInstallerImpl;
50import org.onosproject.sfc.manager.NshSpiIdGenerators;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053051import org.onosproject.sfc.manager.SfcService;
Phaneendra Mandab3555032016-02-08 11:41:53 +053052import org.onosproject.vtnrsc.DefaultFiveTuple;
53import org.onosproject.vtnrsc.FiveTuple;
54import org.onosproject.vtnrsc.FixedIp;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053055import org.onosproject.vtnrsc.FlowClassifier;
56import org.onosproject.vtnrsc.FlowClassifierId;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053057import org.onosproject.vtnrsc.PortChain;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053058import org.onosproject.vtnrsc.PortChainId;
Jonathan Hart51539b82015-10-29 09:53:04 -070059import org.onosproject.vtnrsc.PortPair;
60import org.onosproject.vtnrsc.PortPairGroup;
61import org.onosproject.vtnrsc.PortPairGroupId;
62import org.onosproject.vtnrsc.PortPairId;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053063import org.onosproject.vtnrsc.TenantId;
Phaneendra Mandab3555032016-02-08 11:41:53 +053064import org.onosproject.vtnrsc.VirtualPort;
65import org.onosproject.vtnrsc.VirtualPortId;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053066import org.onosproject.vtnrsc.event.VtnRscEvent;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053067import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053068import org.onosproject.vtnrsc.event.VtnRscListener;
Phaneendra Mandab3555032016-02-08 11:41:53 +053069import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
70import org.onosproject.vtnrsc.portchain.PortChainService;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053071import org.onosproject.vtnrsc.service.VtnRscService;
Phaneendra Mandab3555032016-02-08 11:41:53 +053072import org.onosproject.vtnrsc.virtualport.VirtualPortService;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053073import org.slf4j.Logger;
74
75/**
76 * Provides implementation of SFC Service.
77 */
78@Component(immediate = true)
79@Service
80public class SfcManager implements SfcService {
81
82 private final Logger log = getLogger(getClass());
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053083 private static final String APP_ID = "org.onosproject.app.vtn";
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053084 private static final int SFC_PRIORITY = 1000;
Phaneendra Mandab3555032016-02-08 11:41:53 +053085 private static final int NULL_PORT = 0;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053086
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected VtnRscService vtnRscService;
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected CoreService coreService;
92
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053093 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected PacketService packetService;
95
Phaneendra Mandab3555032016-02-08 11:41:53 +053096 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected PortChainService portChainService;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected FlowClassifierService flowClassifierService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected VirtualPortService virtualPortService;
104
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530105 private SfcPacketProcessor processor = new SfcPacketProcessor();
106
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530107 protected ApplicationId appId;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530108 private ServiceFunctionForwarderService serviceFunctionForwarderService;
109 private FlowClassifierInstallerService flowClassifierInstallerService;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530110
111 private final VtnRscListener vtnRscListener = new InnerVtnRscListener();
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530112
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530113 private ConcurrentMap<PortChainId, NshServicePathId> nshSpiPortChainMap = new ConcurrentHashMap<>();
114
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530115 @Activate
116 public void activate() {
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530117 appId = coreService.registerApplication(APP_ID);
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530118 serviceFunctionForwarderService = new ServiceFunctionForwarderImpl(appId);
119 flowClassifierInstallerService = new FlowClassifierInstallerImpl(appId);
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530120
121 vtnRscService.addListener(vtnRscListener);
122
123 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
124 .register(TenantId.class)
125 .register(PortPairId.class)
126 .register(PortPairGroupId.class)
127 .register(FlowClassifierId.class)
128 .register(PortChainId.class);
129
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530130 packetService.addProcessor(processor, PacketProcessor.director(SFC_PRIORITY));
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530131 log.info("Started");
132 }
133
134 @Deactivate
135 public void deactivate() {
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530136 vtnRscService.removeListener(vtnRscListener);
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530137 packetService.removeProcessor(processor);
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530138 log.info("Stopped");
139 }
140
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530141 /*
142 * Handle events.
143 */
144 private class InnerVtnRscListener implements VtnRscListener {
145 @Override
146 public void event(VtnRscEvent event) {
147
148 if (VtnRscEvent.Type.PORT_PAIR_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530149 PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530150 onPortPairCreated(portPair);
151 } else if (VtnRscEvent.Type.PORT_PAIR_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530152 PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530153 onPortPairDeleted(portPair);
154 } else if (VtnRscEvent.Type.PORT_PAIR_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530155 PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530156 onPortPairDeleted(portPair);
157 onPortPairCreated(portPair);
158 } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530159 PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530160 onPortPairGroupCreated(portPairGroup);
161 } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530162 PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530163 onPortPairGroupDeleted(portPairGroup);
164 } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530165 PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530166 onPortPairGroupDeleted(portPairGroup);
167 onPortPairGroupCreated(portPairGroup);
168 } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530169 FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530170 onFlowClassifierCreated(flowClassifier);
171 } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530172 FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530173 onFlowClassifierDeleted(flowClassifier);
174 } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530175 FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530176 onFlowClassifierDeleted(flowClassifier);
177 onFlowClassifierCreated(flowClassifier);
178 } else if (VtnRscEvent.Type.PORT_CHAIN_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530179 PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530180 onPortChainCreated(portChain);
181 } else if (VtnRscEvent.Type.PORT_CHAIN_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530182 PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530183 onPortChainDeleted(portChain);
184 } else if (VtnRscEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530185 PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530186 onPortChainDeleted(portChain);
187 onPortChainCreated(portChain);
188 }
189 }
190 }
191
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530192 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530193 public void onPortPairCreated(PortPair portPair) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530194 log.debug("onPortPairCreated");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530195 // TODO: Modify forwarding rule on port-pair creation.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530196 }
197
198 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530199 public void onPortPairDeleted(PortPair portPair) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530200 log.debug("onPortPairDeleted");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530201 // TODO: Modify forwarding rule on port-pair deletion.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530202 }
203
204 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530205 public void onPortPairGroupCreated(PortPairGroup portPairGroup) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530206 log.debug("onPortPairGroupCreated");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530207 // TODO: Modify forwarding rule on port-pair-group creation.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530208 }
209
210 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530211 public void onPortPairGroupDeleted(PortPairGroup portPairGroup) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530212 log.debug("onPortPairGroupDeleted");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530213 // TODO: Modify forwarding rule on port-pair-group deletion.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530214 }
215
216 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530217 public void onFlowClassifierCreated(FlowClassifier flowClassifier) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530218 log.debug("onFlowClassifierCreated");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530219 // TODO: Modify forwarding rule on flow-classifier creation.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530220 }
221
222 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530223 public void onFlowClassifierDeleted(FlowClassifier flowClassifier) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530224 log.debug("onFlowClassifierDeleted");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530225 // TODO: Modify forwarding rule on flow-classifier deletion.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530226 }
227
228 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530229 public void onPortChainCreated(PortChain portChain) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700230 NshServicePathId nshSpi;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530231 log.info("onPortChainCreated");
232 if (nshSpiPortChainMap.containsKey(portChain.portChainId())) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700233 nshSpi = nshSpiPortChainMap.get(portChain.portChainId());
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530234 } else {
Jonathan Hart51539b82015-10-29 09:53:04 -0700235 nshSpi = NshServicePathId.of(NshSpiIdGenerators.create());
236 nshSpiPortChainMap.put(portChain.portChainId(), nshSpi);
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530237 }
238
239 // install in OVS.
Jonathan Hart51539b82015-10-29 09:53:04 -0700240 flowClassifierInstallerService.installFlowClassifier(portChain, nshSpi);
241 serviceFunctionForwarderService.installForwardingRule(portChain, nshSpi);
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530242 }
243
244 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530245 public void onPortChainDeleted(PortChain portChain) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530246 log.info("onPortChainDeleted");
247 if (!nshSpiPortChainMap.containsKey(portChain.portChainId())) {
248 throw new ItemNotFoundException("Unable to find NSH SPI");
249 }
250
Jonathan Hart51539b82015-10-29 09:53:04 -0700251 NshServicePathId nshSpi = nshSpiPortChainMap.get(portChain.portChainId());
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530252 // uninstall from OVS.
Jonathan Hart51539b82015-10-29 09:53:04 -0700253 flowClassifierInstallerService.unInstallFlowClassifier(portChain, nshSpi);
254 serviceFunctionForwarderService.unInstallForwardingRule(portChain, nshSpi);
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530255
256 // remove SPI. No longer it will be used.
Jonathan Hart51539b82015-10-29 09:53:04 -0700257 nshSpiPortChainMap.remove(nshSpi);
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530258 }
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530259
260 private class SfcPacketProcessor implements PacketProcessor {
261
Phaneendra Mandab3555032016-02-08 11:41:53 +0530262 /**
263 * Check for given ip match with the fixed ips for the virtual port.
264 *
265 * @param vPortId virtual port id
266 * @param ip ip address to match
267 * @return true if the ip match with the fixed ips in virtual port false otherwise
268 */
269 private boolean checkIpInVirtualPort(VirtualPortId vPortId, IpAddress ip) {
270 boolean found = false;
271 Set<FixedIp> ips = virtualPortService.getPort(vPortId).fixedIps();
272 for (FixedIp fixedIp : ips) {
273 if (fixedIp.ip().equals(ip)) {
274 found = true;
275 break;
276 }
277 }
278 return found;
279 }
280
281 /**
282 * Find the port chain for the received packet.
283 *
284 * @param fiveTuple five tuple info from the packet
285 * @return portChainId id of port chain
286 */
287 private PortChainId findPortChainFromFiveTuple(FiveTuple fiveTuple) {
288
289 PortChainId portChainId = null;
290
291 Iterable<PortChain> portChains = portChainService.getPortChains();
292 if (portChains == null) {
293 log.error("Could not retrive port chain list");
294 }
295
296 // Identify the port chain to which the packet belongs
297 for (final PortChain portChain : portChains) {
298
299 Iterable<FlowClassifierId> flowClassifiers = portChain.flowClassifiers();
300
301 // One port chain can have multiple flow classifiers.
302 for (final FlowClassifierId flowClassifierId : flowClassifiers) {
303
304 FlowClassifier flowClassifier = flowClassifierService.getFlowClassifier(flowClassifierId);
305 boolean match = false;
306 // Check whether protocol is set in flow classifier
307 if (flowClassifier.protocol() != null) {
308 if ((flowClassifier.protocol().equals("TCP") && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) ||
309 (flowClassifier.protocol().equals("UDP") &&
310 fiveTuple.protocol() == IPv4.PROTOCOL_UDP)) {
311 match = true;
312 } else {
313 continue;
314 }
315 }
316
317 // Check whether source ip prefix is set in flow classifier
318 if (flowClassifier.srcIpPrefix() != null) {
319 if (flowClassifier.srcIpPrefix().contains(fiveTuple.ipSrc())) {
320 match = true;
321 } else {
322 continue;
323 }
324 }
325
326 // Check whether destination ip prefix is set in flow classifier
327 if (flowClassifier.dstIpPrefix() != null) {
328 if (flowClassifier.dstIpPrefix().contains(fiveTuple.ipDst())) {
329 match = true;
330 } else {
331 continue;
332 }
333 }
334
335 // Check whether source port is set in flow classifier
336 if (fiveTuple.portSrc().toLong() >= flowClassifier.minSrcPortRange() ||
337 fiveTuple.portSrc().toLong() <= flowClassifier.maxSrcPortRange()) {
338 match = true;
339 } else {
340 continue;
341 }
342
343 // Check whether destination port is set in flow classifier
344 if (fiveTuple.portDst().toLong() >= flowClassifier.minSrcPortRange() ||
345 fiveTuple.portDst().toLong() <= flowClassifier.maxSrcPortRange()) {
346 match = true;
347 } else {
348 continue;
349 }
350
351 // Check whether neutron source port is set in flow classfier
352 if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) {
353 match = checkIpInVirtualPort(VirtualPortId.portId(flowClassifier.srcPort().portId()),
354 fiveTuple.ipSrc());
355 if (!match) {
356 continue;
357 }
358 }
359
360 // Check whether destination neutron destination port is set in flow classifier
361 if ((flowClassifier.dstPort() != null) && (!flowClassifier.dstPort().portId().isEmpty())) {
362 match = checkIpInVirtualPort(VirtualPortId.portId(flowClassifier.dstPort().portId()),
363 fiveTuple.ipDst());
364 if (!match) {
365 continue;
366 }
367 }
368
369 if (match) {
370 portChainId = portChain.portChainId();
371 break;
372 }
373 }
374 }
375 return portChainId;
376 }
377
378
379 /**
380 * Get the tenant id for the given mac address.
381 *
382 * @param mac mac address
383 * @return tenantId tenant id for the given mac address
384 */
385 private TenantId getTenantId(MacAddress mac) {
386 Collection<VirtualPort> virtualPorts = virtualPortService.getPorts();
387 for (VirtualPort virtualPort : virtualPorts) {
388 if (virtualPort.macAddress().equals(mac)) {
389 return virtualPort.tenantId();
390 }
391 }
392 return null;
393 }
394
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530395 @Override
396 public void process(PacketContext context) {
397 Ethernet packet = context.inPacket().parsed();
398 if (packet == null) {
399 return;
400 }
Phaneendra Mandab3555032016-02-08 11:41:53 +0530401 // get the five tuple parameters for the packet
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530402 short ethType = packet.getEtherType();
Phaneendra Mandab3555032016-02-08 11:41:53 +0530403 IpAddress ipSrc = null;
404 IpAddress ipDst = null;
405 int portSrc = 0;
406 int portDst = 0;
407 byte protocol = 0;
408 MacAddress macSrc = packet.getSourceMAC();
409 TenantId tenantId = getTenantId(macSrc);
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530410
411 if (ethType == Ethernet.TYPE_IPV4) {
412 IPv4 ipv4Packet = (IPv4) packet.getPayload();
413 ipSrc = IpAddress.valueOf(ipv4Packet.getSourceAddress());
414 ipDst = IpAddress.valueOf(ipv4Packet.getDestinationAddress());
Phaneendra Mandab3555032016-02-08 11:41:53 +0530415 protocol = ipv4Packet.getProtocol();
416 if (protocol == IPv4.PROTOCOL_TCP) {
417 TCP tcpPacket = (TCP) ipv4Packet.getPayload();
418 portSrc = tcpPacket.getSourcePort();
419 portDst = tcpPacket.getDestinationPort();
420 } else if (protocol == IPv4.PROTOCOL_UDP) {
421 UDP udpPacket = (UDP) ipv4Packet.getPayload();
422 portSrc = udpPacket.getSourcePort();
423 portDst = udpPacket.getDestinationPort();
424 }
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530425 } else if (ethType == Ethernet.TYPE_IPV6) {
Phaneendra Mandab3555032016-02-08 11:41:53 +0530426 return;
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530427 }
428
Phaneendra Mandab3555032016-02-08 11:41:53 +0530429
430 FiveTuple fiveTuple = DefaultFiveTuple.builder()
431 .setIpSrc(ipSrc)
432 .setIpDst(ipDst)
433 .setPortSrc(PortNumber.portNumber(portSrc))
434 .setPortDst(PortNumber.portNumber(portDst))
435 .setProtocol(protocol)
436 .setTenantId(tenantId)
437 .build();
438
439 PortChainId portChainId = findPortChainFromFiveTuple(fiveTuple);
440
441 if (portChainId == null) {
442 log.error("Packet does not match with any classifier");
443 return;
444 }
445
446 // TODO
447 // download the required flow rules for classifier and forwarding
448 // resend the packet back to classifier
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530449 }
450 }
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530451}