blob: 73ac9c5ac222984b8b2338644c8cec9f2b5755f7 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.host.impl;
tomdb0d03f2014-08-27 16:34:15 -070017
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
tom5f38b3a2014-08-27 23:50:54 -070021import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
tomdb0d03f2014-08-27 16:34:15 -070023import org.apache.felix.scr.annotations.Service;
Simon Huntff663742015-05-14 13:33:05 -070024import org.onlab.packet.IpAddress;
25import org.onlab.packet.MacAddress;
26import org.onlab.packet.VlanId;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070027import org.onosproject.net.provider.AbstractListenerProviderRegistry;
Changhoon Yoon541ef712015-05-23 17:18:34 +090028import org.onosproject.core.Permission;
Sahil Lele3a0cdd52015-07-21 14:16:31 -070029import org.onosproject.incubator.net.config.NetworkConfigEvent;
30import org.onosproject.incubator.net.config.NetworkConfigListener;
31import org.onosproject.incubator.net.config.NetworkConfigService;
32import org.onosproject.incubator.net.config.basics.BasicHostConfig;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.ConnectPoint;
Sahil Lele3a0cdd52015-07-21 14:16:31 -070034import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.DeviceId;
36import org.onosproject.net.Host;
37import org.onosproject.net.HostId;
Sahil Lele3a0cdd52015-07-21 14:16:31 -070038import org.onosproject.net.SparseAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.device.DeviceService;
Sahil Lele3a0cdd52015-07-21 14:16:31 -070040import org.onosproject.net.host.DefaultHostDescription;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.host.HostAdminService;
42import org.onosproject.net.host.HostDescription;
43import org.onosproject.net.host.HostEvent;
44import org.onosproject.net.host.HostListener;
45import org.onosproject.net.host.HostProvider;
46import org.onosproject.net.host.HostProviderRegistry;
47import org.onosproject.net.host.HostProviderService;
48import org.onosproject.net.host.HostService;
49import org.onosproject.net.host.HostStore;
50import org.onosproject.net.host.HostStoreDelegate;
51import org.onosproject.net.host.PortAddresses;
52import org.onosproject.net.packet.PacketService;
Brian O'Connorabafb502014-12-02 22:26:20 -080053import org.onosproject.net.provider.AbstractProviderService;
tomdb0d03f2014-08-27 16:34:15 -070054import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070055
Simon Huntff663742015-05-14 13:33:05 -070056import java.util.Set;
57
58import static com.google.common.base.Preconditions.checkNotNull;
Sahil Lele3a0cdd52015-07-21 14:16:31 -070059import static com.google.common.base.Preconditions.checkState;
Changhoon Yoon541ef712015-05-23 17:18:34 +090060import static org.onosproject.security.AppGuard.checkPermission;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070061import static org.slf4j.LoggerFactory.getLogger;
Simon Huntff663742015-05-14 13:33:05 -070062
tomdb0d03f2014-08-27 16:34:15 -070063/**
64 * Provides basic implementation of the host SB & NB APIs.
65 */
66@Component(immediate = true)
67@Service
tom202175a2014-09-19 19:00:11 -070068public class HostManager
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070069 extends AbstractListenerProviderRegistry<HostEvent, HostListener, HostProvider, HostProviderService>
tom89b63c52014-09-16 09:19:51 -070070 implements HostService, HostAdminService, HostProviderRegistry {
tomdb0d03f2014-08-27 16:34:15 -070071
tom5f38b3a2014-08-27 23:50:54 -070072 private final Logger log = getLogger(getClass());
tomdb0d03f2014-08-27 16:34:15 -070073
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070074 public static final String HOST_ID_NULL = "Host ID cannot be null";
tom5f38b3a2014-08-27 23:50:54 -070075
Sahil Lele3a0cdd52015-07-21 14:16:31 -070076 private final NetworkConfigListener networkConfigListener = new InternalNetworkConfigListener();
77
tomc78acee2014-09-24 15:16:55 -070078 private HostStoreDelegate delegate = new InternalStoreDelegate();
79
tom5bcc9462014-09-19 10:11:31 -070080 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 protected HostStore store;
tom7869ad92014-09-09 14:32:08 -070082
tom5f38b3a2014-08-27 23:50:54 -070083 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart70da5122014-10-01 16:37:42 -070084 protected DeviceService deviceService;
85
86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected PacketService packetService;
88
Sahil Lele3a0cdd52015-07-21 14:16:31 -070089 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 protected NetworkConfigService networkConfigService;
91
Jonathan Hart70da5122014-10-01 16:37:42 -070092 private HostMonitor monitor;
tomdb0d03f2014-08-27 16:34:15 -070093
94 @Activate
95 public void activate() {
tomc78acee2014-09-24 15:16:55 -070096 store.setDelegate(delegate);
tom96dfcab2014-08-28 09:26:03 -070097 eventDispatcher.addSink(HostEvent.class, listenerRegistry);
Sahil Lele3a0cdd52015-07-21 14:16:31 -070098 networkConfigService.addListener(networkConfigListener);
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070099 monitor = new HostMonitor(deviceService, packetService, this);
Jonathan Hart8f6f1ea2014-10-03 16:05:19 -0700100 monitor.start();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700101 log.info("Started");
tomdb0d03f2014-08-27 16:34:15 -0700102 }
103
104 @Deactivate
105 public void deactivate() {
tomc78acee2014-09-24 15:16:55 -0700106 store.unsetDelegate(delegate);
tom5f38b3a2014-08-27 23:50:54 -0700107 eventDispatcher.removeSink(HostEvent.class);
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700108 networkConfigService.removeListener(networkConfigListener);
tomdb0d03f2014-08-27 16:34:15 -0700109 log.info("Stopped");
110 }
111
112 @Override
tom5f38b3a2014-08-27 23:50:54 -0700113 protected HostProviderService createProviderService(HostProvider provider) {
Jonathan Hart70da5122014-10-01 16:37:42 -0700114 monitor.registerHostProvider(provider);
tom5f38b3a2014-08-27 23:50:54 -0700115 return new InternalHostProviderService(provider);
tomdb0d03f2014-08-27 16:34:15 -0700116 }
117
tom7869ad92014-09-09 14:32:08 -0700118 @Override
119 public int getHostCount() {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900120 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700121 return store.getHostCount();
122 }
123
124 @Override
125 public Iterable<Host> getHosts() {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900126 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700127 return store.getHosts();
128 }
129
130 @Override
131 public Host getHost(HostId hostId) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900132 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700133 checkNotNull(hostId, HOST_ID_NULL);
134 return store.getHost(hostId);
135 }
136
137 @Override
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700138 public Set<Host> getHostsByVlan(VlanId vlanId) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900139 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700140 return store.getHosts(vlanId);
141 }
142
143 @Override
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700144 public Set<Host> getHostsByMac(MacAddress mac) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900145 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700146 checkNotNull(mac, "MAC address cannot be null");
147 return store.getHosts(mac);
148 }
149
150 @Override
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700151 public Set<Host> getHostsByIp(IpAddress ip) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900152 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700153 checkNotNull(ip, "IP address cannot be null");
154 return store.getHosts(ip);
155 }
156
157 @Override
158 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900159 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700160 checkNotNull(connectPoint, "Connection point cannot be null");
161 return store.getConnectedHosts(connectPoint);
162 }
163
164 @Override
165 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900166 checkPermission(Permission.HOST_READ);
tom7869ad92014-09-09 14:32:08 -0700167 checkNotNull(deviceId, "Device ID cannot be null");
168 return store.getConnectedHosts(deviceId);
169 }
170
171 @Override
Jonathan Hartac60c082014-09-23 08:55:17 -0700172 public void startMonitoringIp(IpAddress ip) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900173 checkPermission(Permission.HOST_EVENT);
Jonathan Hart70da5122014-10-01 16:37:42 -0700174 monitor.addMonitoringFor(ip);
Jonathan Hartfca736c2014-09-19 17:26:59 -0700175 }
176
177 @Override
Jonathan Hartac60c082014-09-23 08:55:17 -0700178 public void stopMonitoringIp(IpAddress ip) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900179 checkPermission(Permission.HOST_EVENT);
Jonathan Hart70da5122014-10-01 16:37:42 -0700180 monitor.stopMonitoring(ip);
Jonathan Hartac60c082014-09-23 08:55:17 -0700181 }
182
183 @Override
184 public void requestMac(IpAddress ip) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700185 // FIXME!!!! Auto-generated method stub
tom7869ad92014-09-09 14:32:08 -0700186 }
187
tom89b63c52014-09-16 09:19:51 -0700188 @Override
189 public void removeHost(HostId hostId) {
190 checkNotNull(hostId, HOST_ID_NULL);
191 HostEvent event = store.removeHost(hostId);
192 if (event != null) {
tom89b63c52014-09-16 09:19:51 -0700193 post(event);
194 }
195 }
196
Jonathan Hartac60c082014-09-23 08:55:17 -0700197 @Override
Jonathan Hart09585c62014-09-23 16:58:04 -0700198 public void bindAddressesToPort(PortAddresses addresses) {
199 store.updateAddressBindings(addresses);
Jonathan Hartac60c082014-09-23 08:55:17 -0700200 }
201
202 @Override
Jonathan Hart09585c62014-09-23 16:58:04 -0700203 public void unbindAddressesFromPort(PortAddresses portAddresses) {
204 store.removeAddressBindings(portAddresses);
205 }
206
207 @Override
208 public void clearAddresses(ConnectPoint connectPoint) {
209 store.clearAddressBindings(connectPoint);
Jonathan Hartac60c082014-09-23 08:55:17 -0700210 }
211
212 @Override
213 public Set<PortAddresses> getAddressBindings() {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900214 checkPermission(Permission.HOST_READ);
Jonathan Hart43c182c2014-09-23 11:13:42 -0700215 return store.getAddressBindings();
Jonathan Hartac60c082014-09-23 08:55:17 -0700216 }
217
218 @Override
Jonathan Harta887ba82014-11-03 15:20:52 -0800219 public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
Changhoon Yoon541ef712015-05-23 17:18:34 +0900220 checkPermission(Permission.HOST_READ);
Jonathan Hart43c182c2014-09-23 11:13:42 -0700221 return store.getAddressBindingsForPort(connectPoint);
Jonathan Hartac60c082014-09-23 08:55:17 -0700222 }
223
tomdb0d03f2014-08-27 16:34:15 -0700224 // Personalized host provider service issued to the supplied provider.
tom7869ad92014-09-09 14:32:08 -0700225 private class InternalHostProviderService
226 extends AbstractProviderService<HostProvider>
tomdb0d03f2014-08-27 16:34:15 -0700227 implements HostProviderService {
tomcfde0622014-09-09 11:02:42 -0700228 InternalHostProviderService(HostProvider provider) {
tomdb0d03f2014-08-27 16:34:15 -0700229 super(provider);
230 }
231
232 @Override
tom7869ad92014-09-09 14:32:08 -0700233 public void hostDetected(HostId hostId, HostDescription hostDescription) {
234 checkNotNull(hostId, HOST_ID_NULL);
235 checkValidity();
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700236 hostDescription = validateHost(hostDescription, hostId);
tom7869ad92014-09-09 14:32:08 -0700237 HostEvent event = store.createOrUpdateHost(provider().id(), hostId,
238 hostDescription);
239 if (event != null) {
tom7869ad92014-09-09 14:32:08 -0700240 post(event);
241 }
tomdb0d03f2014-08-27 16:34:15 -0700242 }
243
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700244 // returns a HostDescription made from the union of the BasicHostConfig
245 // annotations if it exists
246 private HostDescription validateHost(HostDescription hostDescription, HostId hostId) {
247 BasicHostConfig cfg = networkConfigService.getConfig(hostId, BasicHostConfig.class);
248 checkState(cfg == null || cfg.isAllowed(), "Host {} is not allowed", hostId);
249 if (cfg != null) {
250 SparseAnnotations finalSparse = processAnnotations(cfg, hostDescription);
251 hostDescription = new DefaultHostDescription(hostId.mac(),
252 hostDescription.vlan(),
253 hostDescription.location(),
254 finalSparse);
255 }
256 return hostDescription;
257 }
258
tomdb0d03f2014-08-27 16:34:15 -0700259 @Override
tom7869ad92014-09-09 14:32:08 -0700260 public void hostVanished(HostId hostId) {
261 checkNotNull(hostId, HOST_ID_NULL);
262 checkValidity();
263 HostEvent event = store.removeHost(hostId);
264 if (event != null) {
tom7869ad92014-09-09 14:32:08 -0700265 post(event);
266 }
tomdb0d03f2014-08-27 16:34:15 -0700267 }
268 }
tom7869ad92014-09-09 14:32:08 -0700269
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700270 // Supplements or replaces hostDescriptions's annotations with BasicHostConfig's
271 // annotations
272 private SparseAnnotations processAnnotations(BasicHostConfig cfg, HostDescription hostDescription) {
273 SparseAnnotations originalAnnotations = hostDescription.annotations();
274 DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
275 if (cfg.name() != null) {
276 newBuilder.set(cfg.NAME, cfg.name());
277 }
278 if (cfg.latitude() != -1) {
279 newBuilder.set(cfg.LATITUDE, Double.toString(cfg.latitude()));
280 }
281 if (cfg.longitude() != -1) {
282 newBuilder.set(cfg.LONGITUDE, Double.toString(cfg.longitude()));
283 }
284 if (cfg.rackAddress() != null) {
285 newBuilder.set(cfg.RACK_ADDRESS, cfg.rackAddress());
286 }
287 if (cfg.owner() != null) {
288 newBuilder.set(cfg.OWNER, cfg.owner());
289 }
290 DefaultAnnotations newAnnotations = newBuilder.build();
291 return DefaultAnnotations.union(originalAnnotations, newAnnotations);
292 }
293
tomc78acee2014-09-24 15:16:55 -0700294 // Store delegate to re-post events emitted from the store.
295 private class InternalStoreDelegate implements HostStoreDelegate {
296 @Override
297 public void notify(HostEvent event) {
298 post(event);
299 }
300 }
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700301
302 // listens for NetworkConfigEvents of type BasicHostConfig and removes
303 // links that the config does not allow
304 private class InternalNetworkConfigListener implements NetworkConfigListener {
305 @Override
306 public void event(NetworkConfigEvent event) {
307 if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
308 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
309 event.configClass().equals(BasicHostConfig.class)) {
310 log.info("Detected Host network config event {}", event.type());
311 kickOutBadHost(((HostId) event.subject()));
312 }
313 }
314 }
315
316 // checks if the specified host is allowed by the BasicHostConfig
317 // and if not, removes it
318 private void kickOutBadHost(HostId hostId) {
319 BasicHostConfig cfg = networkConfigService.getConfig(hostId, BasicHostConfig.class);
320 if (cfg != null && !cfg.isAllowed()) {
321 Host badHost = getHost(hostId);
322 if (badHost != null) {
323 removeHost(hostId);
324 } else {
325 log.info("Failed removal: Host {} does not exist", hostId);
326 }
327 }
328 }
tomdb0d03f2014-08-27 16:34:15 -0700329}