blob: fefecab3dfb07b862c55eda3bb4311c2c9249b29 [file] [log] [blame]
Charles Chand6d581a2015-11-18 16:51:08 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Charles Chand6d581a2015-11-18 16:51:08 -08003 *
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 */
16
17package org.onosproject.provider.netcfghost;
18
19import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.onlab.packet.IpAddress;
25import org.onlab.packet.MacAddress;
26import org.onlab.packet.VlanId;
27import org.onosproject.core.ApplicationId;
28import org.onosproject.core.CoreService;
Charles Chand6d581a2015-11-18 16:51:08 -080029import org.onosproject.net.Host;
30import org.onosproject.net.HostId;
31import org.onosproject.net.HostLocation;
32import org.onosproject.net.config.NetworkConfigEvent;
33import org.onosproject.net.config.NetworkConfigListener;
34import org.onosproject.net.config.NetworkConfigRegistry;
35import org.onosproject.net.config.basics.BasicHostConfig;
36import org.onosproject.net.host.DefaultHostDescription;
37import org.onosproject.net.host.HostDescription;
38import org.onosproject.net.host.HostProvider;
39import org.onosproject.net.host.HostProviderRegistry;
40import org.onosproject.net.host.HostProviderService;
41import org.onosproject.net.provider.AbstractProvider;
42import org.onosproject.net.provider.ProviderId;
43import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
Charles Chan61fc0d82017-04-28 14:13:36 -070045
46import java.util.Collections;
Charles Chand6d581a2015-11-18 16:51:08 -080047import java.util.Set;
Charles Chan61fc0d82017-04-28 14:13:36 -070048import java.util.stream.Collectors;
Charles Chand6d581a2015-11-18 16:51:08 -080049
50/**
51 * Host provider that uses network config service to discover hosts.
52 */
53@Component(immediate = true)
54public class NetworkConfigHostProvider extends AbstractProvider implements HostProvider {
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected CoreService coreService;
57
58 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
59 protected HostProviderRegistry providerRegistry;
60
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 protected NetworkConfigRegistry networkConfigRegistry;
63
Charles Chand6d581a2015-11-18 16:51:08 -080064 private ApplicationId appId;
Charles Chan6ea94fc2016-05-10 17:29:47 -070065 private static final String APP_NAME = "org.onosproject.netcfghost";
Charles Chanb3007e12016-05-20 10:55:40 -070066 private static final ProviderId PROVIDER_ID = new ProviderId("host", APP_NAME);
Charles Chand6d581a2015-11-18 16:51:08 -080067 protected HostProviderService providerService;
68
69 private final Logger log = LoggerFactory.getLogger(getClass());
70 private final InternalNetworkConfigListener networkConfigListener =
71 new InternalNetworkConfigListener();
72
73 /**
74 * Creates an network config host location provider.
75 */
76 public NetworkConfigHostProvider() {
Charles Chan6ea94fc2016-05-10 17:29:47 -070077 super(PROVIDER_ID);
Charles Chand6d581a2015-11-18 16:51:08 -080078 }
79
80 @Activate
81 protected void activate() {
82 appId = coreService.registerApplication(APP_NAME);
83 providerService = providerRegistry.register(this);
84 networkConfigRegistry.addListener(networkConfigListener);
85 readInitialConfig();
86 log.info("Started");
87 }
88
89 @Deactivate
90 protected void deactivate() {
91 networkConfigRegistry.removeListener(networkConfigListener);
92 providerRegistry.unregister(this);
93 providerService = null;
94 log.info("Stopped");
95 }
96
97 @Override
98 public void triggerProbe(Host host) {
99 /*
Charles Chanb3007e12016-05-20 10:55:40 -0700100 * Note: All hosts are configured in network config host provider.
Charles Chand6d581a2015-11-18 16:51:08 -0800101 * Therefore no probe is required.
102 */
103 }
104
105 /**
106 * Adds host information.
107 * IP information will be appended if host exists.
108 *
109 * @param mac MAC address of the host
110 * @param vlan VLAN ID of the host
Charles Chan61fc0d82017-04-28 14:13:36 -0700111 * @param locations Location of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800112 * @param ips Set of IP addresses of the host
113 */
Charles Chan61fc0d82017-04-28 14:13:36 -0700114 protected void addHost(MacAddress mac, VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips) {
Charles Chand6d581a2015-11-18 16:51:08 -0800115 HostId hid = HostId.hostId(mac, vlan);
Charles Chan7e0e2e62016-04-15 16:30:41 -0700116 HostDescription desc = (ips != null) ?
Charles Chan61fc0d82017-04-28 14:13:36 -0700117 new DefaultHostDescription(mac, vlan, locations, ips, true) :
118 new DefaultHostDescription(mac, vlan, locations, Collections.emptySet(), true);
Charles Chanb1e99242017-07-07 14:11:09 -0700119 providerService.hostDetected(hid, desc, true);
Charles Chand6d581a2015-11-18 16:51:08 -0800120 }
121
122 /**
123 * Updates host information.
124 * IP information will be replaced if host exists.
125 *
126 * @param mac MAC address of the host
127 * @param vlan VLAN ID of the host
Charles Chan61fc0d82017-04-28 14:13:36 -0700128 * @param locations Location of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800129 * @param ips Set of IP addresses of the host
130 */
Charles Chan61fc0d82017-04-28 14:13:36 -0700131 protected void updateHost(MacAddress mac, VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips) {
Charles Chand6d581a2015-11-18 16:51:08 -0800132 HostId hid = HostId.hostId(mac, vlan);
Charles Chan61fc0d82017-04-28 14:13:36 -0700133 HostDescription desc = new DefaultHostDescription(mac, vlan, locations, ips, true);
Charles Chand6d581a2015-11-18 16:51:08 -0800134 providerService.hostDetected(hid, desc, true);
135 }
136
137 /**
138 * Removes host information.
139 *
140 * @param mac MAC address of the host
141 * @param vlan VLAN ID of the host
142 */
143 protected void removeHost(MacAddress mac, VlanId vlan) {
144 HostId hid = HostId.hostId(mac, vlan);
145 providerService.hostVanished(hid);
146 }
147
148 private void readInitialConfig() {
149 networkConfigRegistry.getSubjects(HostId.class).forEach(hostId -> {
150 MacAddress mac = hostId.mac();
151 VlanId vlan = hostId.vlanId();
152 BasicHostConfig hostConfig =
153 networkConfigRegistry.getConfig(hostId, BasicHostConfig.class);
154 Set<IpAddress> ipAddresses = hostConfig.ipAddresses();
Charles Chan61fc0d82017-04-28 14:13:36 -0700155 Set<HostLocation> locations = hostConfig.locations().stream()
156 .map(hostLocation -> new HostLocation(hostLocation, System.currentTimeMillis()))
157 .collect(Collectors.toSet());
158 addHost(mac, vlan, locations, ipAddresses);
Charles Chand6d581a2015-11-18 16:51:08 -0800159 });
160 }
161
162 private class InternalNetworkConfigListener implements NetworkConfigListener {
163 @Override
164 public void event(NetworkConfigEvent event) {
165 // Do not process non-host, register and unregister events
166 if (!event.configClass().equals(BasicHostConfig.class) ||
167 event.type() == NetworkConfigEvent.Type.CONFIG_REGISTERED ||
168 event.type() == NetworkConfigEvent.Type.CONFIG_UNREGISTERED) {
169 return;
170 }
171
172 HostId hostId = (HostId) event.subject();
173 MacAddress mac = hostId.mac();
174 VlanId vlan = hostId.vlanId();
175 BasicHostConfig hostConfig =
176 networkConfigRegistry.getConfig(hostId, BasicHostConfig.class);
177 Set<IpAddress> ipAddresses = null;
Charles Chan61fc0d82017-04-28 14:13:36 -0700178 Set<HostLocation> locations = null;
Charles Chand6d581a2015-11-18 16:51:08 -0800179
180 // Note: There will be no config presented in the CONFIG_REMOVE case
181 if (hostConfig != null) {
182 ipAddresses = hostConfig.ipAddresses();
Charles Chan61fc0d82017-04-28 14:13:36 -0700183 locations = hostConfig.locations().stream()
184 .map(hostLocation -> new HostLocation(hostLocation, System.currentTimeMillis()))
185 .collect(Collectors.toSet());
Charles Chand6d581a2015-11-18 16:51:08 -0800186 }
187
188 switch (event.type()) {
189 case CONFIG_ADDED:
Charles Chan61fc0d82017-04-28 14:13:36 -0700190 addHost(mac, vlan, locations, ipAddresses);
Charles Chand6d581a2015-11-18 16:51:08 -0800191 break;
192 case CONFIG_UPDATED:
Charles Chan61fc0d82017-04-28 14:13:36 -0700193 updateHost(mac, vlan, locations, ipAddresses);
Charles Chand6d581a2015-11-18 16:51:08 -0800194 break;
195 case CONFIG_REMOVED:
196 removeHost(mac, vlan);
197 break;
198 default:
199 break;
200 }
201 }
202 }
203}