blob: 8187edd1201e1a9394733873c7ddd24a85baee47 [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
20import java.util.concurrent.ConcurrentHashMap;
21import java.util.concurrent.ConcurrentMap;
22
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053023import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053026import org.apache.felix.scr.annotations.Reference;
27import org.apache.felix.scr.annotations.ReferenceCardinality;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053028import org.apache.felix.scr.annotations.Service;
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053029import org.onlab.packet.Ethernet;
30import org.onlab.packet.IPv4;
31import org.onlab.packet.IPv6;
32import org.onlab.packet.IpAddress;
33import org.onlab.packet.MacAddress;
34import org.onlab.packet.VlanId;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053035import org.onlab.util.ItemNotFoundException;
Jonathan Hart51539b82015-10-29 09:53:04 -070036import org.onlab.util.KryoNamespace;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053037import org.onosproject.core.ApplicationId;
38import org.onosproject.core.CoreService;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053039import org.onosproject.net.NshServicePathId;
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053040import org.onosproject.net.packet.PacketContext;
41import org.onosproject.net.packet.PacketProcessor;
42import org.onosproject.net.packet.PacketService;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053043import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService;
44import org.onosproject.sfc.forwarder.impl.ServiceFunctionForwarderImpl;
45import org.onosproject.sfc.installer.FlowClassifierInstallerService;
46import org.onosproject.sfc.installer.impl.FlowClassifierInstallerImpl;
47import org.onosproject.sfc.manager.NshSpiIdGenerators;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053048import org.onosproject.sfc.manager.SfcService;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053049import org.onosproject.vtnrsc.FlowClassifier;
50import org.onosproject.vtnrsc.FlowClassifierId;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053051import org.onosproject.vtnrsc.PortChain;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053052import org.onosproject.vtnrsc.PortChainId;
Jonathan Hart51539b82015-10-29 09:53:04 -070053import org.onosproject.vtnrsc.PortPair;
54import org.onosproject.vtnrsc.PortPairGroup;
55import org.onosproject.vtnrsc.PortPairGroupId;
56import org.onosproject.vtnrsc.PortPairId;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053057import org.onosproject.vtnrsc.TenantId;
58import org.onosproject.vtnrsc.event.VtnRscEvent;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053059import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053060import org.onosproject.vtnrsc.event.VtnRscListener;
61import org.onosproject.vtnrsc.service.VtnRscService;
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053062import org.slf4j.Logger;
63
64/**
65 * Provides implementation of SFC Service.
66 */
67@Component(immediate = true)
68@Service
69public class SfcManager implements SfcService {
70
71 private final Logger log = getLogger(getClass());
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053072 private static final String APP_ID = "org.onosproject.app.vtn";
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053073 private static final int SFC_PRIORITY = 1000;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053074
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected VtnRscService vtnRscService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected CoreService coreService;
80
Phaneendra Manda5c8257b2016-02-03 22:07:38 +053081 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 protected PacketService packetService;
83
84 private SfcPacketProcessor processor = new SfcPacketProcessor();
85
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053086 protected ApplicationId appId;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053087 private ServiceFunctionForwarderService serviceFunctionForwarderService;
88 private FlowClassifierInstallerService flowClassifierInstallerService;
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053089
90 private final VtnRscListener vtnRscListener = new InnerVtnRscListener();
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053091
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053092 private ConcurrentMap<PortChainId, NshServicePathId> nshSpiPortChainMap = new ConcurrentHashMap<>();
93
Mahesh Poojary S335e7c32015-10-29 10:16:51 +053094 @Activate
95 public void activate() {
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053096 appId = coreService.registerApplication(APP_ID);
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +053097 serviceFunctionForwarderService = new ServiceFunctionForwarderImpl(appId);
98 flowClassifierInstallerService = new FlowClassifierInstallerImpl(appId);
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +053099
100 vtnRscService.addListener(vtnRscListener);
101
102 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
103 .register(TenantId.class)
104 .register(PortPairId.class)
105 .register(PortPairGroupId.class)
106 .register(FlowClassifierId.class)
107 .register(PortChainId.class);
108
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530109 packetService.addProcessor(processor, PacketProcessor.director(SFC_PRIORITY));
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530110 log.info("Started");
111 }
112
113 @Deactivate
114 public void deactivate() {
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530115 vtnRscService.removeListener(vtnRscListener);
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530116 packetService.removeProcessor(processor);
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530117 log.info("Stopped");
118 }
119
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530120 /*
121 * Handle events.
122 */
123 private class InnerVtnRscListener implements VtnRscListener {
124 @Override
125 public void event(VtnRscEvent event) {
126
127 if (VtnRscEvent.Type.PORT_PAIR_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530128 PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530129 onPortPairCreated(portPair);
130 } else if (VtnRscEvent.Type.PORT_PAIR_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530131 PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530132 onPortPairDeleted(portPair);
133 } else if (VtnRscEvent.Type.PORT_PAIR_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530134 PortPair portPair = ((VtnRscEventFeedback) event.subject()).portPair();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530135 onPortPairDeleted(portPair);
136 onPortPairCreated(portPair);
137 } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530138 PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530139 onPortPairGroupCreated(portPairGroup);
140 } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530141 PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530142 onPortPairGroupDeleted(portPairGroup);
143 } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530144 PortPairGroup portPairGroup = ((VtnRscEventFeedback) event.subject()).portPairGroup();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530145 onPortPairGroupDeleted(portPairGroup);
146 onPortPairGroupCreated(portPairGroup);
147 } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530148 FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530149 onFlowClassifierCreated(flowClassifier);
150 } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530151 FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530152 onFlowClassifierDeleted(flowClassifier);
153 } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530154 FlowClassifier flowClassifier = ((VtnRscEventFeedback) event.subject()).flowClassifier();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530155 onFlowClassifierDeleted(flowClassifier);
156 onFlowClassifierCreated(flowClassifier);
157 } else if (VtnRscEvent.Type.PORT_CHAIN_PUT == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530158 PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530159 onPortChainCreated(portChain);
160 } else if (VtnRscEvent.Type.PORT_CHAIN_DELETE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530161 PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530162 onPortChainDeleted(portChain);
163 } else if (VtnRscEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530164 PortChain portChain = (PortChain) ((VtnRscEventFeedback) event.subject()).portChain();
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530165 onPortChainDeleted(portChain);
166 onPortChainCreated(portChain);
167 }
168 }
169 }
170
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530171 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530172 public void onPortPairCreated(PortPair portPair) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530173 log.debug("onPortPairCreated");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530174 // TODO: Modify forwarding rule on port-pair creation.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530175 }
176
177 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530178 public void onPortPairDeleted(PortPair portPair) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530179 log.debug("onPortPairDeleted");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530180 // TODO: Modify forwarding rule on port-pair deletion.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530181 }
182
183 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530184 public void onPortPairGroupCreated(PortPairGroup portPairGroup) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530185 log.debug("onPortPairGroupCreated");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530186 // TODO: Modify forwarding rule on port-pair-group creation.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530187 }
188
189 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530190 public void onPortPairGroupDeleted(PortPairGroup portPairGroup) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530191 log.debug("onPortPairGroupDeleted");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530192 // TODO: Modify forwarding rule on port-pair-group deletion.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530193 }
194
195 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530196 public void onFlowClassifierCreated(FlowClassifier flowClassifier) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530197 log.debug("onFlowClassifierCreated");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530198 // TODO: Modify forwarding rule on flow-classifier creation.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530199 }
200
201 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530202 public void onFlowClassifierDeleted(FlowClassifier flowClassifier) {
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530203 log.debug("onFlowClassifierDeleted");
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530204 // TODO: Modify forwarding rule on flow-classifier deletion.
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530205 }
206
207 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530208 public void onPortChainCreated(PortChain portChain) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700209 NshServicePathId nshSpi;
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530210 log.info("onPortChainCreated");
211 if (nshSpiPortChainMap.containsKey(portChain.portChainId())) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700212 nshSpi = nshSpiPortChainMap.get(portChain.portChainId());
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530213 } else {
Jonathan Hart51539b82015-10-29 09:53:04 -0700214 nshSpi = NshServicePathId.of(NshSpiIdGenerators.create());
215 nshSpiPortChainMap.put(portChain.portChainId(), nshSpi);
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530216 }
217
218 // install in OVS.
Jonathan Hart51539b82015-10-29 09:53:04 -0700219 flowClassifierInstallerService.installFlowClassifier(portChain, nshSpi);
220 serviceFunctionForwarderService.installForwardingRule(portChain, nshSpi);
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530221 }
222
223 @Override
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530224 public void onPortChainDeleted(PortChain portChain) {
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530225 log.info("onPortChainDeleted");
226 if (!nshSpiPortChainMap.containsKey(portChain.portChainId())) {
227 throw new ItemNotFoundException("Unable to find NSH SPI");
228 }
229
Jonathan Hart51539b82015-10-29 09:53:04 -0700230 NshServicePathId nshSpi = nshSpiPortChainMap.get(portChain.portChainId());
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530231 // uninstall from OVS.
Jonathan Hart51539b82015-10-29 09:53:04 -0700232 flowClassifierInstallerService.unInstallFlowClassifier(portChain, nshSpi);
233 serviceFunctionForwarderService.unInstallForwardingRule(portChain, nshSpi);
Mahesh Poojary Huawei15092f62015-12-10 11:09:02 +0530234
235 // remove SPI. No longer it will be used.
Jonathan Hart51539b82015-10-29 09:53:04 -0700236 nshSpiPortChainMap.remove(nshSpi);
Mahesh Poojary S335e7c32015-10-29 10:16:51 +0530237 }
Phaneendra Manda5c8257b2016-02-03 22:07:38 +0530238
239 private class SfcPacketProcessor implements PacketProcessor {
240
241 @Override
242 public void process(PacketContext context) {
243 Ethernet packet = context.inPacket().parsed();
244 if (packet == null) {
245 return;
246 }
247 // get the five tupple parameters for the packet
248 short ethType = packet.getEtherType();
249 VlanId vlanId = VlanId.vlanId(packet.getVlanID());
250 MacAddress srcMac = packet.getSourceMAC();
251 MacAddress dstMac = packet.getDestinationMAC();
252 IpAddress ipSrc;
253 IpAddress ipDst;
254
255 if (ethType == Ethernet.TYPE_IPV4) {
256 IPv4 ipv4Packet = (IPv4) packet.getPayload();
257 ipSrc = IpAddress.valueOf(ipv4Packet.getSourceAddress());
258 ipDst = IpAddress.valueOf(ipv4Packet.getDestinationAddress());
259 } else if (ethType == Ethernet.TYPE_IPV6) {
260 IPv6 ipv6Packet = (IPv6) packet.getPayload();
261 ipSrc = IpAddress.valueOf(ipv6Packet.getSourceAddress().toString());
262 ipDst = IpAddress.valueOf(ipv6Packet.getDestinationAddress().toString());
263 }
264
265 //todo
266 //identify the port chain to which the packet belongs
267 }
268 }
Mahesh Poojary Sc9c10f92015-11-30 17:18:05 +0530269}