blob: 13c765b9dfebc4e569ef791c4db82228dcd622e8 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
alshabib4906fab2014-09-29 23:58:12 -070019package org.onlab.onos.mobility;
20import static org.slf4j.LoggerFactory.getLogger;
21
22import java.util.Collection;
23import java.util.List;
24
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;
30import org.onlab.onos.ApplicationId;
alshabib92c65ad2014-10-08 21:56:05 -070031import org.onlab.onos.CoreService;
alshabib4906fab2014-09-29 23:58:12 -070032import org.onlab.onos.net.Device;
33import org.onlab.onos.net.Host;
34import org.onlab.onos.net.device.DeviceService;
35import org.onlab.onos.net.flow.FlowRule;
36import org.onlab.onos.net.flow.FlowRuleService;
37import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
38import org.onlab.onos.net.flow.criteria.Criterion;
39import org.onlab.onos.net.flow.criteria.Criterion.Type;
40import org.onlab.onos.net.host.HostEvent;
41import org.onlab.onos.net.host.HostListener;
42import org.onlab.onos.net.host.HostService;
43import 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;
70
71 @Activate
72 public void activate() {
alshabib92c65ad2014-10-08 21:56:05 -070073 appId = coreService.registerApplication("org.onlab.onos.mobility");
alshabib4906fab2014-09-29 23:58:12 -070074 hostService.addListener(new InternalHostListener());
75 log.info("Started with Application ID {}", appId.id());
76 }
77
78 @Deactivate
79 public void deactivate() {
80 flowRuleService.removeFlowRulesById(appId);
81 log.info("Stopped");
82 }
83
84 public class InternalHostListener
85 implements HostListener {
86
87 @Override
88 public void event(HostEvent event) {
89 switch (event.type()) {
90 case HOST_ADDED:
91 case HOST_REMOVED:
92 case HOST_UPDATED:
93 // don't care if a host has been added, removed.
94 break;
95 case HOST_MOVED:
96 log.info("Host {} has moved; cleaning up.", event.subject());
97 cleanup(event.subject());
98 break;
99
100 default:
101 break;
102
103 }
104
105 }
106
alshabib0ff17ad2014-09-30 09:46:40 -0700107 /**
108 * For a given host, remove any flow rule which references it's addresses.
109 * @param host the host to clean up for
110 */
alshabib4906fab2014-09-29 23:58:12 -0700111 private void cleanup(Host host) {
112 Iterable<Device> devices = deviceService.getDevices();
113 List<FlowRule> flowRules = Lists.newLinkedList();
114 for (Device device : devices) {
115 flowRules.addAll(cleanupDevice(device, host));
116 }
117 FlowRule[] flows = new FlowRule[flowRules.size()];
118 flows = flowRules.toArray(flows);
119 flowRuleService.removeFlowRules(flows);
120 }
121
122 private Collection<? extends FlowRule> cleanupDevice(Device device, Host host) {
123 List<FlowRule> flowRules = Lists.newLinkedList();
124 MacAddress mac = host.mac();
125 for (FlowRule rule : flowRuleService.getFlowEntries(device.id())) {
126 for (Criterion c : rule.selector().criteria()) {
127 if (c.type() == Type.ETH_DST || c.type() == Type.ETH_SRC) {
128 EthCriterion eth = (EthCriterion) c;
129 if (eth.mac().equals(mac)) {
130 flowRules.add(rule);
alshabib4906fab2014-09-29 23:58:12 -0700131 }
132 }
133 }
134 }
135 //TODO: handle ip cleanup
136 return flowRules;
137 }
138
139 }
140
141}
142
143