blob: 5c7343b33c94e3de0081436be94257e2903c2802 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.mobility;
Brian O'Connorca37aa22015-12-11 13:54:36 -080017import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
18import static org.onlab.util.Tools.groupedThreads;
alshabib4906fab2014-09-29 23:58:12 -070019import static org.slf4j.LoggerFactory.getLogger;
20
21import java.util.Collection;
22import java.util.List;
Brian O'Connorca37aa22015-12-11 13:54:36 -080023import java.util.concurrent.ExecutorService;
alshabib4906fab2014-09-29 23:58:12 -070024
25import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
32import org.onosproject.net.Device;
33import org.onosproject.net.Host;
34import org.onosproject.net.device.DeviceService;
35import org.onosproject.net.flow.FlowRule;
36import org.onosproject.net.flow.FlowRuleService;
Sho SHIMIZUfbc80e52015-04-28 10:41:58 -070037import org.onosproject.net.flow.criteria.EthCriterion;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.flow.criteria.Criterion;
39import org.onosproject.net.flow.criteria.Criterion.Type;
40import org.onosproject.net.host.HostEvent;
41import org.onosproject.net.host.HostListener;
42import org.onosproject.net.host.HostService;
alshabib4906fab2014-09-29 23:58:12 -070043import org.onlab.packet.MacAddress;
44import org.slf4j.Logger;
45
46import com.google.common.collect.Lists;
47
48
49/**
alshabib0ff17ad2014-09-30 09:46:40 -070050 * Sample mobility application. Cleans up flowmods when a host moves.
alshabib4906fab2014-09-29 23:58:12 -070051 */
52@Component(immediate = true)
53public class HostMobility {
54
55 private final Logger log = getLogger(getClass());
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected HostService hostService;
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected FlowRuleService flowRuleService;
62
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 protected DeviceService deviceService;
65
alshabib92c65ad2014-10-08 21:56:05 -070066 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected CoreService coreService;
68
alshabib4906fab2014-09-29 23:58:12 -070069 private ApplicationId appId;
Brian O'Connorca37aa22015-12-11 13:54:36 -080070 private ExecutorService eventHandler;
Charles Chanae060a32016-06-28 00:29:05 -070071 private final HostListener hostListener = new InternalHostListener();
alshabib4906fab2014-09-29 23:58:12 -070072
73 @Activate
74 public void activate() {
Brian O'Connorabafb502014-12-02 22:26:20 -080075 appId = coreService.registerApplication("org.onosproject.mobility");
HIGUCHI Yutad9e01052016-04-14 09:31:42 -070076 eventHandler = newSingleThreadScheduledExecutor(groupedThreads("onos/app-mobility", "event-handler", log));
Charles Chanae060a32016-06-28 00:29:05 -070077 hostService.addListener(hostListener);
alshabib4906fab2014-09-29 23:58:12 -070078 log.info("Started with Application ID {}", appId.id());
79 }
80
81 @Deactivate
82 public void deactivate() {
Brian O'Connorca37aa22015-12-11 13:54:36 -080083 // TODO we never actually add any flow rules
alshabib4906fab2014-09-29 23:58:12 -070084 flowRuleService.removeFlowRulesById(appId);
Charles Chanae060a32016-06-28 00:29:05 -070085 hostService.removeListener(hostListener);
Brian O'Connorca37aa22015-12-11 13:54:36 -080086 eventHandler.shutdown();
alshabib4906fab2014-09-29 23:58:12 -070087 log.info("Stopped");
88 }
89
90 public class InternalHostListener
Brian O'Connorca37aa22015-12-11 13:54:36 -080091 implements HostListener {
alshabib4906fab2014-09-29 23:58:12 -070092
93 @Override
94 public void event(HostEvent event) {
95 switch (event.type()) {
96 case HOST_ADDED:
97 case HOST_REMOVED:
98 case HOST_UPDATED:
99 // don't care if a host has been added, removed.
100 break;
101 case HOST_MOVED:
102 log.info("Host {} has moved; cleaning up.", event.subject());
Brian O'Connorca37aa22015-12-11 13:54:36 -0800103 eventHandler.execute(() -> cleanup(event.subject()));
alshabib4906fab2014-09-29 23:58:12 -0700104 break;
105
106 default:
107 break;
alshabib4906fab2014-09-29 23:58:12 -0700108 }
alshabib4906fab2014-09-29 23:58:12 -0700109 }
110
alshabib0ff17ad2014-09-30 09:46:40 -0700111 /**
112 * For a given host, remove any flow rule which references it's addresses.
113 * @param host the host to clean up for
114 */
alshabib4906fab2014-09-29 23:58:12 -0700115 private void cleanup(Host host) {
116 Iterable<Device> devices = deviceService.getDevices();
117 List<FlowRule> flowRules = Lists.newLinkedList();
118 for (Device device : devices) {
119 flowRules.addAll(cleanupDevice(device, host));
120 }
121 FlowRule[] flows = new FlowRule[flowRules.size()];
122 flows = flowRules.toArray(flows);
123 flowRuleService.removeFlowRules(flows);
124 }
125
126 private Collection<? extends FlowRule> cleanupDevice(Device device, Host host) {
127 List<FlowRule> flowRules = Lists.newLinkedList();
128 MacAddress mac = host.mac();
129 for (FlowRule rule : flowRuleService.getFlowEntries(device.id())) {
130 for (Criterion c : rule.selector().criteria()) {
131 if (c.type() == Type.ETH_DST || c.type() == Type.ETH_SRC) {
132 EthCriterion eth = (EthCriterion) c;
133 if (eth.mac().equals(mac)) {
134 flowRules.add(rule);
alshabib4906fab2014-09-29 23:58:12 -0700135 }
136 }
137 }
138 }
alshabib4906fab2014-09-29 23:58:12 -0700139 return flowRules;
140 }
alshabib4906fab2014-09-29 23:58:12 -0700141 }
alshabib4906fab2014-09-29 23:58:12 -0700142}
143
144