blob: a0be2d9f00c2b6efcf35526e13c81484fa666ede [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;
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070024import org.onlab.packet.EthType;
Charles Chand6d581a2015-11-18 16:51:08 -080025import org.onlab.packet.IpAddress;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.VlanId;
28import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
Charles Chand6d581a2015-11-18 16:51:08 -080030import org.onosproject.net.Host;
31import org.onosproject.net.HostId;
32import org.onosproject.net.HostLocation;
33import org.onosproject.net.config.NetworkConfigEvent;
34import org.onosproject.net.config.NetworkConfigListener;
35import org.onosproject.net.config.NetworkConfigRegistry;
36import org.onosproject.net.config.basics.BasicHostConfig;
37import org.onosproject.net.host.DefaultHostDescription;
38import org.onosproject.net.host.HostDescription;
39import org.onosproject.net.host.HostProvider;
40import org.onosproject.net.host.HostProviderRegistry;
41import org.onosproject.net.host.HostProviderService;
42import org.onosproject.net.provider.AbstractProvider;
43import org.onosproject.net.provider.ProviderId;
44import org.slf4j.Logger;
45import org.slf4j.LoggerFactory;
Charles Chan61fc0d82017-04-28 14:13:36 -070046
47import java.util.Collections;
Charles Chand6d581a2015-11-18 16:51:08 -080048import java.util.Set;
Charles Chan61fc0d82017-04-28 14:13:36 -070049import java.util.stream.Collectors;
Charles Chand6d581a2015-11-18 16:51:08 -080050
51/**
52 * Host provider that uses network config service to discover hosts.
53 */
54@Component(immediate = true)
55public class NetworkConfigHostProvider extends AbstractProvider implements HostProvider {
56 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 protected CoreService coreService;
58
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected HostProviderRegistry providerRegistry;
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected NetworkConfigRegistry networkConfigRegistry;
64
Charles Chand6d581a2015-11-18 16:51:08 -080065 private ApplicationId appId;
Charles Chan6ea94fc2016-05-10 17:29:47 -070066 private static final String APP_NAME = "org.onosproject.netcfghost";
Charles Chanb3007e12016-05-20 10:55:40 -070067 private static final ProviderId PROVIDER_ID = new ProviderId("host", APP_NAME);
Charles Chand6d581a2015-11-18 16:51:08 -080068 protected HostProviderService providerService;
69
70 private final Logger log = LoggerFactory.getLogger(getClass());
71 private final InternalNetworkConfigListener networkConfigListener =
72 new InternalNetworkConfigListener();
73
74 /**
75 * Creates an network config host location provider.
76 */
77 public NetworkConfigHostProvider() {
Charles Chan6ea94fc2016-05-10 17:29:47 -070078 super(PROVIDER_ID);
Charles Chand6d581a2015-11-18 16:51:08 -080079 }
80
81 @Activate
82 protected void activate() {
83 appId = coreService.registerApplication(APP_NAME);
84 providerService = providerRegistry.register(this);
85 networkConfigRegistry.addListener(networkConfigListener);
86 readInitialConfig();
87 log.info("Started");
88 }
89
90 @Deactivate
91 protected void deactivate() {
92 networkConfigRegistry.removeListener(networkConfigListener);
93 providerRegistry.unregister(this);
94 providerService = null;
95 log.info("Stopped");
96 }
97
98 @Override
99 public void triggerProbe(Host host) {
100 /*
Charles Chanb3007e12016-05-20 10:55:40 -0700101 * Note: All hosts are configured in network config host provider.
Charles Chand6d581a2015-11-18 16:51:08 -0800102 * Therefore no probe is required.
103 */
104 }
105
106 /**
107 * Adds host information.
108 * IP information will be appended if host exists.
109 *
110 * @param mac MAC address of the host
111 * @param vlan VLAN ID of the host
Charles Chan61fc0d82017-04-28 14:13:36 -0700112 * @param locations Location of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800113 * @param ips Set of IP addresses of the host
114 */
Charles Chan61fc0d82017-04-28 14:13:36 -0700115 protected void addHost(MacAddress mac, VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips) {
Charles Chand6d581a2015-11-18 16:51:08 -0800116 HostId hid = HostId.hostId(mac, vlan);
Charles Chan7e0e2e62016-04-15 16:30:41 -0700117 HostDescription desc = (ips != null) ?
Charles Chan61fc0d82017-04-28 14:13:36 -0700118 new DefaultHostDescription(mac, vlan, locations, ips, true) :
119 new DefaultHostDescription(mac, vlan, locations, Collections.emptySet(), true);
Charles Chanb1e99242017-07-07 14:11:09 -0700120 providerService.hostDetected(hid, desc, true);
Charles Chand6d581a2015-11-18 16:51:08 -0800121 }
122
123 /**
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700124 * Adds host information.
125 * IP information will be appended if host exists.
126 *
127 * @param mac MAC address of the host
128 * @param vlan VLAN ID of the host
129 * @param locations Location of the host
130 * @param ips Set of IP addresses of the host
131 * @param innerVlan host inner VLAN identifier
132 * @param outerTpid outer TPID of a host
133 */
134 protected void addHost(MacAddress mac, VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips,
135 VlanId innerVlan, EthType outerTpid) {
136 HostId hid = HostId.hostId(mac, vlan);
137 HostDescription desc = (ips != null) ?
138 new DefaultHostDescription(mac, vlan, locations, ips,
139 innerVlan, outerTpid, true) :
140 new DefaultHostDescription(mac, vlan, locations, Collections.emptySet(),
141 innerVlan, outerTpid, true);
142 providerService.hostDetected(hid, desc, true);
143 }
144
145 /**
Charles Chand6d581a2015-11-18 16:51:08 -0800146 * Updates host information.
147 * IP information will be replaced if host exists.
148 *
149 * @param mac MAC address of the host
150 * @param vlan VLAN ID of the host
Charles Chan61fc0d82017-04-28 14:13:36 -0700151 * @param locations Location of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800152 * @param ips Set of IP addresses of the host
153 */
Charles Chan61fc0d82017-04-28 14:13:36 -0700154 protected void updateHost(MacAddress mac, VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips) {
Charles Chand6d581a2015-11-18 16:51:08 -0800155 HostId hid = HostId.hostId(mac, vlan);
Charles Chan61fc0d82017-04-28 14:13:36 -0700156 HostDescription desc = new DefaultHostDescription(mac, vlan, locations, ips, true);
Charles Chand6d581a2015-11-18 16:51:08 -0800157 providerService.hostDetected(hid, desc, true);
158 }
159
160 /**
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700161 * Updates host information.
162 * IP information will be replaced if host exists.
163 *
164 * @param mac MAC address of the host
165 * @param vlan VLAN ID of the host
166 * @param locations Location of the host
167 * @param ips Set of IP addresses of the host
168 * @param innerVlan host inner VLAN identifier
169 * @param outerTpid outer TPID of a host
170 */
171 protected void updateHost(MacAddress mac, VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips,
172 VlanId innerVlan, EthType outerTpid) {
173 HostId hid = HostId.hostId(mac, vlan);
174 HostDescription desc = new DefaultHostDescription(mac, vlan, locations, ips,
175 innerVlan, outerTpid, true);
176 providerService.hostDetected(hid, desc, true);
177 }
178
179 /**
Charles Chand6d581a2015-11-18 16:51:08 -0800180 * Removes host information.
181 *
182 * @param mac MAC address of the host
183 * @param vlan VLAN ID of the host
184 */
185 protected void removeHost(MacAddress mac, VlanId vlan) {
186 HostId hid = HostId.hostId(mac, vlan);
187 providerService.hostVanished(hid);
188 }
189
190 private void readInitialConfig() {
191 networkConfigRegistry.getSubjects(HostId.class).forEach(hostId -> {
192 MacAddress mac = hostId.mac();
193 VlanId vlan = hostId.vlanId();
194 BasicHostConfig hostConfig =
195 networkConfigRegistry.getConfig(hostId, BasicHostConfig.class);
196 Set<IpAddress> ipAddresses = hostConfig.ipAddresses();
Charles Chan61fc0d82017-04-28 14:13:36 -0700197 Set<HostLocation> locations = hostConfig.locations().stream()
198 .map(hostLocation -> new HostLocation(hostLocation, System.currentTimeMillis()))
199 .collect(Collectors.toSet());
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700200 VlanId innerVlan = hostConfig.innerVlan();
201 EthType outerTpid = hostConfig.outerTpid();
202 addHost(mac, vlan, locations, ipAddresses, innerVlan, outerTpid);
Charles Chand6d581a2015-11-18 16:51:08 -0800203 });
204 }
205
206 private class InternalNetworkConfigListener implements NetworkConfigListener {
207 @Override
208 public void event(NetworkConfigEvent event) {
209 // Do not process non-host, register and unregister events
210 if (!event.configClass().equals(BasicHostConfig.class) ||
211 event.type() == NetworkConfigEvent.Type.CONFIG_REGISTERED ||
212 event.type() == NetworkConfigEvent.Type.CONFIG_UNREGISTERED) {
213 return;
214 }
215
216 HostId hostId = (HostId) event.subject();
217 MacAddress mac = hostId.mac();
218 VlanId vlan = hostId.vlanId();
Charles Chanb34a0bd2017-09-12 13:32:41 -0700219 BasicHostConfig hostConfig = networkConfigRegistry.getConfig(hostId, BasicHostConfig.class);
Charles Chand6d581a2015-11-18 16:51:08 -0800220 Set<IpAddress> ipAddresses = null;
Charles Chan61fc0d82017-04-28 14:13:36 -0700221 Set<HostLocation> locations = null;
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700222 VlanId innerVlan = VlanId.NONE;
223 EthType outerTpid = EthType.EtherType.UNKNOWN.ethType();
Charles Chand6d581a2015-11-18 16:51:08 -0800224
225 // Note: There will be no config presented in the CONFIG_REMOVE case
226 if (hostConfig != null) {
227 ipAddresses = hostConfig.ipAddresses();
Charles Chanb34a0bd2017-09-12 13:32:41 -0700228 locations = hostConfig.locations();
229 if (locations == null || locations.size() < 1) {
230 log.debug("Ignore network config event without host locations {}", event);
231 return;
232 }
233 locations = locations.stream()
Charles Chan61fc0d82017-04-28 14:13:36 -0700234 .map(hostLocation -> new HostLocation(hostLocation, System.currentTimeMillis()))
235 .collect(Collectors.toSet());
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700236 innerVlan = hostConfig.innerVlan();
237 outerTpid = hostConfig.outerTpid();
Charles Chand6d581a2015-11-18 16:51:08 -0800238 }
239
240 switch (event.type()) {
241 case CONFIG_ADDED:
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700242 addHost(mac, vlan, locations, ipAddresses, innerVlan, outerTpid);
Charles Chand6d581a2015-11-18 16:51:08 -0800243 break;
244 case CONFIG_UPDATED:
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700245 updateHost(mac, vlan, locations, ipAddresses, innerVlan, outerTpid);
Charles Chand6d581a2015-11-18 16:51:08 -0800246 break;
247 case CONFIG_REMOVED:
248 removeHost(mac, vlan);
249 break;
250 default:
251 break;
252 }
253 }
254 }
255}