blob: 69ea60aac54f9a4fcbc026c584bf506ea8297fd4 [file] [log] [blame]
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +09003 *
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.ofagent.impl;
17
18import com.google.common.collect.ImmutableSet;
Claudine Chiuce8ccc62017-08-16 10:06:20 -040019import com.google.common.collect.Lists;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090020import io.netty.channel.ChannelOutboundInvoker;
21import io.netty.channel.nio.NioEventLoopGroup;
22import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Component;
24import org.apache.felix.scr.annotations.Deactivate;
25import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
27import org.apache.felix.scr.annotations.Service;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090028import org.onosproject.cluster.ClusterService;
29import org.onosproject.cluster.LeadershipService;
30import org.onosproject.cluster.NodeId;
31import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
33import org.onosproject.incubator.net.virtual.NetworkId;
Hyunsun Moon53381e82017-03-28 19:58:28 +090034import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
35import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090036import org.onosproject.incubator.net.virtual.VirtualNetworkService;
Claudine Chiu785ef2d2017-07-04 13:13:28 -040037import org.onosproject.incubator.net.virtual.VirtualPort;
Claudine Chiu5c184e12017-08-08 21:21:38 -040038import org.onosproject.net.ConnectPoint;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090039import org.onosproject.net.Device;
40import org.onosproject.net.DeviceId;
Claudine Chiu5c184e12017-08-08 21:21:38 -040041import org.onosproject.net.Link;
Claudine Chiu785ef2d2017-07-04 13:13:28 -040042import org.onosproject.net.Port;
Claudine Chiu5c184e12017-08-08 21:21:38 -040043import org.onosproject.net.PortNumber;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090044import org.onosproject.net.device.DeviceEvent;
45import org.onosproject.net.device.DeviceListener;
46import org.onosproject.net.device.DeviceService;
Claudine Chiu2729ffd2017-07-31 21:38:27 -040047import org.onosproject.net.device.PortStatistics;
Claudine Chiuce8ccc62017-08-16 10:06:20 -040048import org.onosproject.net.flow.FlowEntry;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090049import org.onosproject.net.flow.FlowRuleEvent;
50import org.onosproject.net.flow.FlowRuleListener;
51import org.onosproject.net.flow.FlowRuleService;
Claudine Chiuce8ccc62017-08-16 10:06:20 -040052import org.onosproject.net.flow.TableStatisticsEntry;
53import org.onosproject.net.group.Group;
54import org.onosproject.net.group.GroupService;
Claudine Chiu5c184e12017-08-08 21:21:38 -040055import org.onosproject.net.link.LinkService;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090056import org.onosproject.net.packet.PacketContext;
57import org.onosproject.net.packet.PacketProcessor;
58import org.onosproject.net.packet.PacketService;
59import org.onosproject.ofagent.api.OFAgent;
60import org.onosproject.ofagent.api.OFAgentEvent;
61import org.onosproject.ofagent.api.OFAgentListener;
62import org.onosproject.ofagent.api.OFAgentService;
63import org.onosproject.ofagent.api.OFController;
64import org.onosproject.ofagent.api.OFSwitch;
65import org.onosproject.ofagent.api.OFSwitchCapabilities;
66import org.onosproject.ofagent.api.OFSwitchService;
67import org.projectfloodlight.openflow.types.DatapathId;
68import org.slf4j.Logger;
69import org.slf4j.LoggerFactory;
70
71import java.net.InetSocketAddress;
72import java.net.SocketAddress;
Claudine Chiuce8ccc62017-08-16 10:06:20 -040073import java.util.ArrayList;
Claudine Chiu2729ffd2017-07-31 21:38:27 -040074import java.util.List;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090075import java.util.Objects;
76import java.util.Set;
77import java.util.concurrent.ConcurrentHashMap;
78import java.util.concurrent.ExecutorService;
79import java.util.stream.Collectors;
80
81import static com.google.common.base.Preconditions.checkArgument;
82import static org.onlab.util.BoundedThreadPool.newSingleThreadExecutor;
83import static org.onlab.util.Tools.groupedThreads;
Hyunsun Moon53381e82017-03-28 19:58:28 +090084import static org.onosproject.ofagent.api.OFAgent.State.STARTED;
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090085import static org.onosproject.ofagent.api.OFAgentService.APPLICATION_NAME;
86
87/**
88 * Manages OF switches.
89 */
90@Component(immediate = true)
91@Service
92public class OFSwitchManager implements OFSwitchService {
93
94 private final Logger log = LoggerFactory.getLogger(getClass());
95
Hyunsun Moon53381e82017-03-28 19:58:28 +090096 private static final OFSwitchCapabilities DEFAULT_CAPABILITIES =
97 DefaultOFSwitchCapabilities.builder()
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +090098 .flowStats()
99 .tableStats()
100 .portStats()
101 .groupStats()
102 .queueStats()
103 .ipReasm()
104 .portBlocked()
105 .build();
106
107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
108 protected CoreService coreService;
109
110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
111 protected LeadershipService leadershipService;
112
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
114 protected ClusterService clusterService;
115
116 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 protected VirtualNetworkService virtualNetService;
118
119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
120 protected OFAgentService ofAgentService;
121
122 private final ConcurrentHashMap<DeviceId, OFSwitch> ofSwitchMap = new ConcurrentHashMap<>();
123 private final ExecutorService eventExecutor = newSingleThreadExecutor(
124 groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
125 private final OFAgentListener ofAgentListener = new InternalOFAgentListener();
Hyunsun Moon53381e82017-03-28 19:58:28 +0900126 private final VirtualNetworkListener vNetworkListener = new InternalVirtualNetworkListener();
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900127 private final DeviceListener deviceListener = new InternalDeviceListener();
128 private final FlowRuleListener flowRuleListener = new InternalFlowRuleListener();
129 private final PacketProcessor packetProcessor = new InternalPacketProcessor();
130
131 private NioEventLoopGroup ioWorker;
132 private ApplicationId appId;
133 private NodeId localId;
134
135 @Activate
136 protected void activate() {
137 appId = coreService.registerApplication(APPLICATION_NAME);
138 localId = clusterService.getLocalNode().id();
139 ioWorker = new NioEventLoopGroup();
Hyunsun Moon53381e82017-03-28 19:58:28 +0900140
141 ofAgentService.agents().forEach(this::processOFAgentCreated);
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900142 ofAgentService.addListener(ofAgentListener);
Hyunsun Moon53381e82017-03-28 19:58:28 +0900143 virtualNetService.addListener(vNetworkListener);
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900144
145 log.info("Started");
146 }
147
148 @Deactivate
149 protected void deactivate() {
Hyunsun Moon53381e82017-03-28 19:58:28 +0900150 virtualNetService.removeListener(vNetworkListener);
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900151 ofAgentService.removeListener(ofAgentListener);
152 ofAgentService.agents().forEach(this::processOFAgentStopped);
153
154 ioWorker.shutdownGracefully();
155 eventExecutor.shutdown();
156
157 log.info("Stopped");
158 }
159
160 @Override
161 public Set<OFSwitch> ofSwitches() {
162 return ImmutableSet.copyOf(ofSwitchMap.values());
163 }
164
165 @Override
166 public Set<OFSwitch> ofSwitches(NetworkId networkId) {
167 Set<OFSwitch> ofSwitches = devices(networkId).stream()
168 .map(ofSwitchMap::get)
169 .filter(Objects::nonNull)
170 .collect(Collectors.toSet());
171 return ImmutableSet.copyOf(ofSwitches);
172 }
173
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400174 @Override
Claudine Chiu2729ffd2017-07-31 21:38:27 -0400175 public OFSwitch ofSwitch(NetworkId networkId, DeviceId deviceId) {
176 return ofSwitchMap.get(deviceId);
177 }
178
179 @Override
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400180 public Set<Port> ports(NetworkId networkId, DeviceId deviceId) {
181 Set<Port> ports = virtualNetService.getVirtualPorts(networkId, deviceId)
182 .stream()
183 .collect(Collectors.toSet());
184 return ImmutableSet.copyOf(ports);
185 }
186
Claudine Chiu2729ffd2017-07-31 21:38:27 -0400187 @Override
188 public List<PortStatistics> getPortStatistics(NetworkId networkId, DeviceId deviceId) {
189 DeviceService deviceService = virtualNetService.get(networkId, DeviceService.class);
190 List<PortStatistics> portStatistics = deviceService.getPortStatistics(deviceId);
191 return portStatistics;
192 }
193
Claudine Chiu5c184e12017-08-08 21:21:38 -0400194 @Override
195 public ConnectPoint neighbour(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
196 ConnectPoint cp = new ConnectPoint(deviceId, portNumber);
197 LinkService linkService = virtualNetService.get(networkId, LinkService.class);
198 Set<Link> links = linkService.getEgressLinks(cp);
199 log.trace("neighbour cp {} egressLinks {}", cp, links);
200 if (links != null && links.size() > 0) {
201 Link link = links.iterator().next();
202 return link.src();
203 }
204 return null;
205 }
206
Claudine Chiuce8ccc62017-08-16 10:06:20 -0400207 @Override
208 public List<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId) {
209 FlowRuleService flowRuleService = virtualNetService.get(networkId, FlowRuleService.class);
210 Iterable<FlowEntry> entries = flowRuleService.getFlowEntries(deviceId);
211 return Lists.newArrayList(entries);
212 }
213
214 @Override
215 public List<TableStatisticsEntry> getFlowTableStatistics(NetworkId networkId, DeviceId deviceId) {
216 FlowRuleService flowRuleService = virtualNetService.get(networkId, FlowRuleService.class);
217 Iterable<TableStatisticsEntry> entries = flowRuleService.getFlowTableStatistics(deviceId);
218 if (entries == null) {
219 entries = new ArrayList<>();
220 }
221 return Lists.newArrayList(entries);
222 }
223
224 @Override
225 public List<Group> getGroups(NetworkId networkId, DeviceId deviceId) {
226 GroupService groupService = virtualNetService.get(networkId, GroupService.class);
227 Iterable<Group> entries = groupService.getGroups(deviceId);
228 return Lists.newArrayList(entries);
229 }
230
Hyunsun Moon53381e82017-03-28 19:58:28 +0900231 private void addOFSwitch(NetworkId networkId, DeviceId deviceId) {
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900232 OFSwitch ofSwitch = DefaultOFSwitch.of(
233 dpidWithDeviceId(deviceId),
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400234 DEFAULT_CAPABILITIES, networkId, deviceId,
235 virtualNetService.getServiceDirectory());
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900236 ofSwitchMap.put(deviceId, ofSwitch);
Hyunsun Moon53381e82017-03-28 19:58:28 +0900237 log.info("Added virtual OF switch for {}", deviceId);
238
239 OFAgent ofAgent = ofAgentService.agent(networkId);
Eric Tangdf833c82017-06-04 22:55:49 +0800240 if (ofAgent == null) {
241 log.error("OFAgent for network {} does not exist", networkId);
242 return;
243 }
244
Hyunsun Moon53381e82017-03-28 19:58:28 +0900245 if (ofAgent.state() == STARTED) {
246 connectController(ofSwitch, ofAgent.controllers());
247 }
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900248 }
249
250 private void deleteOFSwitch(DeviceId deviceId) {
Hyunsun Moon53381e82017-03-28 19:58:28 +0900251 OFSwitch ofSwitch = ofSwitchMap.get(deviceId);
252 ofSwitch.controllerChannels().forEach(ChannelOutboundInvoker::disconnect);
253
254 ofSwitchMap.remove(deviceId);
255 log.info("Removed virtual OFSwitch for {}", deviceId);
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900256 }
257
258 private void connectController(OFSwitch ofSwitch, Set<OFController> controllers) {
259 controllers.forEach(controller -> {
260 OFConnectionHandler connectionHandler = new OFConnectionHandler(
261 ofSwitch,
262 controller,
263 ioWorker);
264 connectionHandler.connect();
265 });
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900266 }
267
268 private void disconnectController(OFSwitch ofSwitch, Set<OFController> controllers) {
269 Set<SocketAddress> controllerAddrs = controllers.stream()
Hyunsun Moon53381e82017-03-28 19:58:28 +0900270 .map(ctrl -> new InetSocketAddress(
271 ctrl.ip().toInetAddress(), ctrl.port().toInt()))
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900272 .collect(Collectors.toSet());
273
274 ofSwitch.controllerChannels().stream()
275 .filter(channel -> controllerAddrs.contains(channel.remoteAddress()))
276 .forEach(ChannelOutboundInvoker::disconnect);
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900277 }
278
279 private Set<DeviceId> devices(NetworkId networkId) {
Hyunsun Moon53381e82017-03-28 19:58:28 +0900280 Set<DeviceId> deviceIds = virtualNetService.getVirtualDevices(networkId)
281 .stream()
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900282 .map(Device::id)
283 .collect(Collectors.toSet());
284 return ImmutableSet.copyOf(deviceIds);
285 }
286
287 private DatapathId dpidWithDeviceId(DeviceId deviceId) {
288 String strDeviceId = deviceId.toString().split(":")[1];
289 checkArgument(strDeviceId.length() == 16, "Invalid device ID " + strDeviceId);
290
291 String resultedHexString = "";
292 for (int i = 0; i < 8; i++) {
293 resultedHexString = resultedHexString + strDeviceId.charAt(2 * i)
294 + strDeviceId.charAt(2 * i + 1);
295 if (i != 7) {
296 resultedHexString += ":";
297 }
298 }
299 return DatapathId.of(resultedHexString);
300 }
301
302 private void processOFAgentCreated(OFAgent ofAgent) {
Hyunsun Moon53381e82017-03-28 19:58:28 +0900303 devices(ofAgent.networkId()).forEach(deviceId -> {
304 addOFSwitch(ofAgent.networkId(), deviceId);
305 });
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900306 }
307
308 private void processOFAgentRemoved(OFAgent ofAgent) {
309 devices(ofAgent.networkId()).forEach(this::deleteOFSwitch);
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900310 }
311
312 private void processOFAgentStarted(OFAgent ofAgent) {
313 devices(ofAgent.networkId()).forEach(deviceId -> {
314 OFSwitch ofSwitch = ofSwitchMap.get(deviceId);
315 if (ofSwitch != null) {
316 connectController(ofSwitch, ofAgent.controllers());
317 }
318 });
319
Hyunsun Moon53381e82017-03-28 19:58:28 +0900320 DeviceService deviceService = virtualNetService.get(
321 ofAgent.networkId(),
322 DeviceService.class);
323 deviceService.addListener(deviceListener);
324
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900325 PacketService packetService = virtualNetService.get(
326 ofAgent.networkId(),
327 PacketService.class);
328 packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
329
330 FlowRuleService flowRuleService = virtualNetService.get(
331 ofAgent.networkId(),
332 FlowRuleService.class);
333 flowRuleService.addListener(flowRuleListener);
334 }
335
336 private void processOFAgentStopped(OFAgent ofAgent) {
337 devices(ofAgent.networkId()).forEach(deviceId -> {
338 OFSwitch ofSwitch = ofSwitchMap.get(deviceId);
339 if (ofSwitch != null) {
340 disconnectController(ofSwitch, ofAgent.controllers());
341 }
342 });
343
Hyunsun Moon53381e82017-03-28 19:58:28 +0900344 DeviceService deviceService = virtualNetService.get(
345 ofAgent.networkId(),
346 DeviceService.class);
347 deviceService.removeListener(deviceListener);
348
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900349 PacketService packetService = virtualNetService.get(
350 ofAgent.networkId(),
351 PacketService.class);
352 packetService.removeProcessor(packetProcessor);
353
354 FlowRuleService flowRuleService = virtualNetService.get(
355 ofAgent.networkId(),
356 FlowRuleService.class);
357 flowRuleService.removeListener(flowRuleListener);
358 }
359
Hyunsun Moon53381e82017-03-28 19:58:28 +0900360 private class InternalVirtualNetworkListener implements VirtualNetworkListener {
361
362 @Override
363 public void event(VirtualNetworkEvent event) {
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400364 log.trace("Vnet event {}", event);
Hyunsun Moon53381e82017-03-28 19:58:28 +0900365 switch (event.type()) {
366 case VIRTUAL_DEVICE_ADDED:
367 eventExecutor.execute(() -> {
368 log.debug("Virtual device {} added to network {}",
369 event.virtualDevice().id(),
370 event.subject());
371 addOFSwitch(event.subject(), event.virtualDevice().id());
372 });
373 break;
374 case VIRTUAL_DEVICE_UPDATED:
375 // TODO handle device availability updates
376 break;
377 case VIRTUAL_DEVICE_REMOVED:
378 eventExecutor.execute(() -> {
379 log.debug("Virtual device {} removed from network {}",
380 event.virtualDevice().id(),
381 event.subject());
382 deleteOFSwitch(event.virtualDevice().id());
383 });
384 break;
385 case NETWORK_UPDATED:
386 case NETWORK_REMOVED:
387 case NETWORK_ADDED:
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400388 break;
Hyunsun Moon53381e82017-03-28 19:58:28 +0900389 case VIRTUAL_PORT_ADDED:
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400390 eventExecutor.execute(() -> {
391 OFSwitch ofSwitch = ofSwitch(event.virtualPort());
392 if (ofSwitch != null) {
393 ofSwitch.processPortAdded(event.virtualPort());
394 log.debug("Virtual port {} added to network {}",
395 event.virtualPort(),
396 event.subject());
397 }
398 });
399 break;
Hyunsun Moon53381e82017-03-28 19:58:28 +0900400 case VIRTUAL_PORT_UPDATED:
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400401 break;
Hyunsun Moon53381e82017-03-28 19:58:28 +0900402 case VIRTUAL_PORT_REMOVED:
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400403 eventExecutor.execute(() -> {
404 OFSwitch ofSwitch = ofSwitch(event.virtualPort());
405 if (ofSwitch != null) {
406 ofSwitch.processPortRemoved(event.virtualPort());
407 log.debug("Virtual port {} removed from network {}",
408 event.virtualPort(),
409 event.subject());
410 }
411 });
412 break;
Hyunsun Moon53381e82017-03-28 19:58:28 +0900413 default:
414 // do nothing
415 break;
416 }
417 }
Claudine Chiu785ef2d2017-07-04 13:13:28 -0400418
419 private OFSwitch ofSwitch(VirtualPort virtualPort) {
420 OFSwitch ofSwitch = ofSwitchMap.get(virtualPort.element().id());
421 if (ofSwitch == null) {
422 log.warn("Switch does not exist for port {}", virtualPort);
423 } else {
424 log.trace("Switch exists for port {}", virtualPort);
425 }
426 return ofSwitch;
427 }
Hyunsun Moon53381e82017-03-28 19:58:28 +0900428 }
429
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900430 private class InternalOFAgentListener implements OFAgentListener {
431
432 @Override
433 public boolean isRelevant(OFAgentEvent event) {
434 return Objects.equals(localId, leadershipService.getLeader(appId.name()));
435 }
436
437 @Override
438 public void event(OFAgentEvent event) {
439 switch (event.type()) {
440 case OFAGENT_CREATED:
441 eventExecutor.execute(() -> {
442 OFAgent ofAgent = event.subject();
443 log.debug("Processing OFAgent created: {}", ofAgent);
444 processOFAgentCreated(ofAgent);
445 });
446 break;
447 case OFAGENT_REMOVED:
448 eventExecutor.execute(() -> {
449 OFAgent ofAgent = event.subject();
450 log.debug("Processing OFAgent removed: {}", ofAgent);
451 processOFAgentRemoved(ofAgent);
452 });
453 break;
454 case OFAGENT_CONTROLLER_ADDED:
455 // TODO handle additional controller
456 break;
457 case OFAGENT_CONTROLLER_REMOVED:
458 // TODO handle removed controller
459 break;
460 case OFAGENT_STARTED:
461 eventExecutor.execute(() -> {
462 OFAgent ofAgent = event.subject();
463 log.debug("Processing OFAgent started: {}", ofAgent);
464 processOFAgentStarted(ofAgent);
465 });
466 break;
467 case OFAGENT_STOPPED:
468 eventExecutor.execute(() -> {
469 OFAgent ofAgent = event.subject();
470 log.debug("Processing OFAgent stopped: {}", ofAgent);
471 processOFAgentStopped(ofAgent);
472 });
473 break;
474 default:
475 // do nothing
476 break;
477 }
478 }
479 }
480
481 private class InternalDeviceListener implements DeviceListener {
482
483 @Override
484 public void event(DeviceEvent event) {
485 switch (event.type()) {
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900486 case DEVICE_AVAILABILITY_CHANGED:
Hyunsun Moon53381e82017-03-28 19:58:28 +0900487 case DEVICE_ADDED:
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900488 case DEVICE_UPDATED:
Hyunsun Moon53381e82017-03-28 19:58:28 +0900489 case DEVICE_REMOVED:
Hyunsun Moonf4ba44f2017-03-14 03:25:52 +0900490 case DEVICE_SUSPENDED:
491 case PORT_ADDED:
492 // TODO handle event
493 case PORT_REMOVED:
494 // TODO handle event
495 case PORT_STATS_UPDATED:
496 case PORT_UPDATED:
497 default:
498 break;
499 }
500 }
501 }
502
503 private class InternalPacketProcessor implements PacketProcessor {
504
505 @Override
506 public void process(PacketContext context) {
507 // TODO handle packet-in
508 }
509 }
510
511 private class InternalFlowRuleListener implements FlowRuleListener {
512
513 @Override
514 public void event(FlowRuleEvent event) {
515 // TODO handle flow rule event
516 }
517 }
518}