blob: d669d72c76b32fdd2a038699ea6a1d77580ea48e [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.packet.impl;
alshabib7674db42014-09-12 23:40:46 -070017
alshabib7674db42014-09-12 23:40:46 -070018import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080024import org.onosproject.core.ApplicationId;
Thomas Vachuska6cba4952015-04-22 12:38:22 -070025import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.Device;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080027import org.onosproject.net.device.DeviceEvent;
28import org.onosproject.net.device.DeviceListener;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.net.device.DeviceService;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080030import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.FlowRule;
32import org.onosproject.net.flow.FlowRuleService;
33import org.onosproject.net.flow.TrafficSelector;
34import org.onosproject.net.flow.TrafficTreatment;
Jonathan Hart17d00452015-04-21 17:10:00 -070035import org.onosproject.net.flowobjective.DefaultForwardingObjective;
36import org.onosproject.net.flowobjective.FlowObjectiveService;
37import org.onosproject.net.flowobjective.ForwardingObjective;
38import org.onosproject.net.flowobjective.Objective;
39import org.onosproject.net.flowobjective.ObjectiveContext;
40import org.onosproject.net.flowobjective.ObjectiveError;
alshabib42947782015-03-31 14:59:06 -070041import org.onosproject.net.packet.DefaultPacketRequest;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.packet.OutboundPacket;
43import org.onosproject.net.packet.PacketContext;
44import org.onosproject.net.packet.PacketEvent;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080045import org.onosproject.net.packet.PacketPriority;
Brian O'Connorabafb502014-12-02 22:26:20 -080046import org.onosproject.net.packet.PacketProcessor;
47import org.onosproject.net.packet.PacketProvider;
48import org.onosproject.net.packet.PacketProviderRegistry;
49import org.onosproject.net.packet.PacketProviderService;
alshabib42947782015-03-31 14:59:06 -070050import org.onosproject.net.packet.PacketRequest;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import org.onosproject.net.packet.PacketService;
52import org.onosproject.net.packet.PacketStore;
53import org.onosproject.net.packet.PacketStoreDelegate;
54import org.onosproject.net.provider.AbstractProviderRegistry;
55import org.onosproject.net.provider.AbstractProviderService;
alshabib7674db42014-09-12 23:40:46 -070056import org.slf4j.Logger;
57
alshabib089bb772015-03-03 18:26:26 -080058import java.util.Map;
alshabib089bb772015-03-03 18:26:26 -080059import java.util.concurrent.ConcurrentHashMap;
60
61import static com.google.common.base.Preconditions.checkNotNull;
62import static org.slf4j.LoggerFactory.getLogger;
63
alshabib7674db42014-09-12 23:40:46 -070064/**
65 * Provides a basic implementation of the packet SB & NB APIs.
alshabib7674db42014-09-12 23:40:46 -070066 */
67@Component(immediate = true)
68@Service
tom202175a2014-09-19 19:00:11 -070069public class PacketManager
Thomas Vachuska6cba4952015-04-22 12:38:22 -070070 extends AbstractProviderRegistry<PacketProvider, PacketProviderService>
71 implements PacketService, PacketProviderRegistry {
alshabib7674db42014-09-12 23:40:46 -070072
73 private final Logger log = getLogger(getClass());
74
Jonathan Hart4f60f982014-10-27 08:11:17 -070075 private final PacketStoreDelegate delegate = new InternalStoreDelegate();
76
alshabib7674db42014-09-12 23:40:46 -070077 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Thomas Vachuska6cba4952015-04-22 12:38:22 -070078 private CoreService coreService;
79
80 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart17d00452015-04-21 17:10:00 -070081 private FlowObjectiveService objectiveService;
82
83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
alshabib7674db42014-09-12 23:40:46 -070084 private DeviceService deviceService;
85
Jonathan Hart4f60f982014-10-27 08:11:17 -070086 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080087 private FlowRuleService flowService;
88
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart4f60f982014-10-27 08:11:17 -070090 private PacketStore store;
91
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080092 private final DeviceListener deviceListener = new InternalDeviceListener();
93
Jonathan Hart4f60f982014-10-27 08:11:17 -070094 private final Map<Integer, PacketProcessor> processors = new ConcurrentHashMap<>();
alshabib7674db42014-09-12 23:40:46 -070095
Thomas Vachuska6cba4952015-04-22 12:38:22 -070096 private ApplicationId appId;
97
alshabib7674db42014-09-12 23:40:46 -070098 @Activate
99 public void activate() {
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700100 appId = coreService.getAppId(CoreService.CORE_APP_NAME);
Jonathan Hart4f60f982014-10-27 08:11:17 -0700101 store.setDelegate(delegate);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800102 deviceService.addListener(deviceListener);
alshabib7674db42014-09-12 23:40:46 -0700103 log.info("Started");
104 }
105
106 @Deactivate
107 public void deactivate() {
Jonathan Hart4f60f982014-10-27 08:11:17 -0700108 store.unsetDelegate(delegate);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800109 deviceService.removeListener(deviceListener);
alshabib7674db42014-09-12 23:40:46 -0700110 log.info("Stopped");
111 }
112
113 @Override
114 public void addProcessor(PacketProcessor processor, int priority) {
alshabib030111e2014-09-15 15:56:42 -0700115 checkNotNull(processor, "Processor cannot be null");
alshabibd58d3522014-09-13 17:14:53 -0700116 processors.put(priority, processor);
alshabib7674db42014-09-12 23:40:46 -0700117 }
118
119 @Override
120 public void removeProcessor(PacketProcessor processor) {
tomc370ebd2014-09-16 01:25:21 -0700121 checkNotNull(processor, "Processor cannot be null");
alshabibd58d3522014-09-13 17:14:53 -0700122 processors.values().remove(processor);
alshabib7674db42014-09-12 23:40:46 -0700123 }
124
125 @Override
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800126 public void requestPackets(TrafficSelector selector, PacketPriority priority,
127 ApplicationId appId) {
128 checkNotNull(selector, "Selector cannot be null");
129 checkNotNull(appId, "Application ID cannot be null");
130
131 PacketRequest request =
alshabib42947782015-03-31 14:59:06 -0700132 new DefaultPacketRequest(selector, priority, appId, FlowRule.Type.DEFAULT);
Saurav Dasc313c402015-02-27 10:09:47 -0800133
alshabib42947782015-03-31 14:59:06 -0700134 if (store.requestPackets(request)) {
135 pushToAllDevices(request);
136 }
Saurav Dasc313c402015-02-27 10:09:47 -0800137 }
138
139 @Override
140 public void requestPackets(TrafficSelector selector, PacketPriority priority,
141 ApplicationId appId, FlowRule.Type tableType) {
142 checkNotNull(selector, "Selector cannot be null");
143 checkNotNull(appId, "Application ID cannot be null");
144 checkNotNull(tableType, "Table Type cannot be null. For requesting packets +"
145 + "without table hints, use other methods in the packetService API");
146
147 PacketRequest request =
alshabib42947782015-03-31 14:59:06 -0700148 new DefaultPacketRequest(selector, priority, appId, tableType);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800149
alshabib42947782015-03-31 14:59:06 -0700150 if (store.requestPackets(request)) {
alshabib089bb772015-03-03 18:26:26 -0800151 pushToAllDevices(request);
152 }
alshabib42947782015-03-31 14:59:06 -0700153
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800154 }
155
156 /**
157 * Pushes a packet request flow rule to all devices.
158 *
159 * @param request the packet request
160 */
161 private void pushToAllDevices(PacketRequest request) {
162 for (Device device : deviceService.getDevices()) {
alshabib42947782015-03-31 14:59:06 -0700163 pushRule(device, request);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800164 }
165 }
166
167 /**
168 * Pushes flow rules to the device to request packets be sent to the
169 * controller.
170 *
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700171 * @param device the device to push the rules to
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800172 * @param request the packet request
173 */
174 private void pushRule(Device device, PacketRequest request) {
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800175 // Everything is pre-provisioned on ROADMs
176 if (device.type().equals(Device.Type.ROADM)) {
177 return;
178 }
179
Jonathan Hart17d00452015-04-21 17:10:00 -0700180 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
181 .punt()
182 .build();
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800183
Jonathan Hart17d00452015-04-21 17:10:00 -0700184 ForwardingObjective forwarding = DefaultForwardingObjective.builder()
185 .withPriority(request.priority().priorityValue())
186 .withSelector(request.selector())
187 .fromApp(appId)
188 .withFlag(ForwardingObjective.Flag.VERSATILE)
189 .withTreatment(treatment)
190 .makePermanent()
191 .add(new ObjectiveContext() {
192 @Override
193 public void onSuccess(Objective objective) { }
194
195 @Override
196 public void onError(Objective objective, ObjectiveError error) {
Saurav Das3d038262015-04-23 12:36:58 -0700197 log.warn("Failed to install packet request {}: {}",
198 request, error);
Jonathan Hart17d00452015-04-21 17:10:00 -0700199 }
200 });
201
202 objectiveService.forward(device.id(), forwarding);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800203 }
204
205 @Override
alshabib7674db42014-09-12 23:40:46 -0700206 public void emit(OutboundPacket packet) {
tomc370ebd2014-09-16 01:25:21 -0700207 checkNotNull(packet, "Packet cannot be null");
Jonathan Hart4f60f982014-10-27 08:11:17 -0700208
209 store.emit(packet);
210 }
211
212 private void localEmit(OutboundPacket packet) {
alshabib7674db42014-09-12 23:40:46 -0700213 final Device device = deviceService.getDevice(packet.sendThrough());
Jonathan Hart7466d612014-11-24 17:09:53 -0800214
215 if (device == null) {
216 return;
217 }
218
alshabib7674db42014-09-12 23:40:46 -0700219 final PacketProvider packetProvider = getProvider(device.providerId());
Jonathan Hart7466d612014-11-24 17:09:53 -0800220
alshabib3d643ec2014-10-22 18:33:00 -0700221 if (packetProvider != null) {
222 packetProvider.emit(packet);
223 }
alshabib7674db42014-09-12 23:40:46 -0700224 }
225
226 @Override
tomc370ebd2014-09-16 01:25:21 -0700227 protected PacketProviderService createProviderService(PacketProvider provider) {
alshabib7674db42014-09-12 23:40:46 -0700228 return new InternalPacketProviderService(provider);
229 }
230
231 // Personalized link provider service issued to the supplied provider.
232 private class InternalPacketProviderService
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700233 extends AbstractProviderService<PacketProvider>
234 implements PacketProviderService {
alshabib7674db42014-09-12 23:40:46 -0700235
236 protected InternalPacketProviderService(PacketProvider provider) {
237 super(provider);
238 }
239
240 @Override
241 public void processPacket(PacketContext context) {
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800242 // TODO filter packets sent to processors based on registrations
alshabibd58d3522014-09-13 17:14:53 -0700243 for (PacketProcessor processor : processors.values()) {
alshabib7674db42014-09-12 23:40:46 -0700244 processor.process(context);
245 }
246 }
247
248 }
Jonathan Hart4f60f982014-10-27 08:11:17 -0700249
250 /**
251 * Internal callback from the packet store.
252 */
253 private class InternalStoreDelegate
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700254 implements PacketStoreDelegate {
Jonathan Hart4f60f982014-10-27 08:11:17 -0700255 @Override
256 public void notify(PacketEvent event) {
257 localEmit(event.subject());
258 }
259 }
260
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800261 /**
262 * Internal listener for device service events.
263 */
264 private class InternalDeviceListener implements DeviceListener {
265 @Override
266 public void event(DeviceEvent event) {
267 Device device = event.subject();
sangho864a9db22015-04-28 12:06:31 -0700268 switch (event.type()) {
269 case DEVICE_ADDED:
270 case DEVICE_AVAILABILITY_CHANGED:
271 if (deviceService.isAvailable(event.subject().id())) {
272 for (PacketRequest request : store.existingRequests()) {
273 pushRule(device, request);
274 }
275 }
276 break;
277 default:
278 break;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800279 }
280 }
281 }
282
alshabibae857582014-09-12 23:53:10 -0700283}