blob: c3d6264492e04a60ddb838e43e8b7044f693516e [file] [log] [blame]
Luca Prete9c2ee072016-02-16 11:00:44 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Luca Prete9c2ee072016-02-16 11:00:44 -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
Luca Prete9c2ee072016-02-16 11:00:44 -080014 */
15package org.onosproject.vpls;
16
nosignal5fd282e2016-09-16 16:11:40 -070017import com.google.common.collect.ImmutableSet;
18import com.google.common.collect.Lists;
Luca Prete9c2ee072016-02-16 11:00:44 -080019import com.google.common.collect.SetMultimap;
nosignal5fd282e2016-09-16 16:11:40 -070020import com.google.common.collect.Sets;
Luca Prete9c2ee072016-02-16 11:00:44 -080021import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.VlanId;
28import org.onosproject.app.ApplicationService;
29import org.onosproject.core.ApplicationId;
30import org.onosproject.core.CoreService;
nosignal5fd282e2016-09-16 16:11:40 -070031import org.onosproject.incubator.net.intf.Interface;
Luca Pretea8854822016-04-26 16:30:55 -070032import org.onosproject.incubator.net.intf.InterfaceEvent;
33import org.onosproject.incubator.net.intf.InterfaceListener;
Luca Prete9c2ee072016-02-16 11:00:44 -080034import org.onosproject.incubator.net.intf.InterfaceService;
Luca Prete092e8952016-10-26 16:25:56 +020035import org.onosproject.net.EncapsulationType;
nosignal5fd282e2016-09-16 16:11:40 -070036import org.onosproject.net.FilteredConnectPoint;
Luca Prete9c2ee072016-02-16 11:00:44 -080037import org.onosproject.net.Host;
nosignal5fd282e2016-09-16 16:11:40 -070038import org.onosproject.net.config.NetworkConfigEvent;
39import org.onosproject.net.config.NetworkConfigListener;
40import org.onosproject.net.config.NetworkConfigService;
41import org.onosproject.net.flow.DefaultTrafficSelector;
42import org.onosproject.net.flow.TrafficSelector;
43import org.onosproject.net.flow.criteria.Criterion;
44import org.onosproject.net.flow.criteria.VlanIdCriterion;
Luca Prete9c2ee072016-02-16 11:00:44 -080045import org.onosproject.net.host.HostEvent;
46import org.onosproject.net.host.HostListener;
47import org.onosproject.net.host.HostService;
nosignal5fd282e2016-09-16 16:11:40 -070048import org.onosproject.net.intent.Intent;
Luca Prete9c2ee072016-02-16 11:00:44 -080049import org.onosproject.net.intent.IntentService;
nosignal5fd282e2016-09-16 16:11:40 -070050import org.onosproject.net.intent.Key;
Luca Prete9c2ee072016-02-16 11:00:44 -080051import org.onosproject.routing.IntentSynchronizationService;
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010052import org.onosproject.vpls.config.VplsConfigService;
Luca Prete9c2ee072016-02-16 11:00:44 -080053import org.slf4j.Logger;
54
nosignal5fd282e2016-09-16 16:11:40 -070055import java.util.Collection;
56import java.util.HashSet;
57import java.util.List;
Luca Prete9c2ee072016-02-16 11:00:44 -080058import java.util.Set;
nosignal5fd282e2016-09-16 16:11:40 -070059import java.util.stream.Collectors;
Luca Prete9c2ee072016-02-16 11:00:44 -080060
nosignal5fd282e2016-09-16 16:11:40 -070061import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
62import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010063import static org.slf4j.LoggerFactory.getLogger;
Luca Prete9c2ee072016-02-16 11:00:44 -080064
65/**
Luca Prete092e8952016-10-26 16:25:56 +020066 * Application to create L2 broadcast overlay networks using VLANs.
Luca Prete9c2ee072016-02-16 11:00:44 -080067 */
68@Component(immediate = true)
69public class Vpls {
nosignal5fd282e2016-09-16 16:11:40 -070070 static final String VPLS_APP = "org.onosproject.vpls";
71
72 private static final String HOST_FCP_NOT_FOUND =
73 "Filtered connected point for host {} not found";
74 private static final String HOST_EVENT = "Received HostEvent {}";
75 private static final String INTF_CONF_EVENT =
76 "Received InterfaceConfigEvent {}";
77 private static final String NET_CONF_EVENT =
78 "Received NetworkConfigEvent {}";
Yi Tseng28767f02016-09-13 04:27:20 -070079
Luca Prete9c2ee072016-02-16 11:00:44 -080080 private final Logger log = getLogger(getClass());
81
82 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
83 protected ApplicationService applicationService;
84
85 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 protected CoreService coreService;
87
88 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 protected HostService hostService;
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected IntentService intentService;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected InterfaceService interfaceService;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected IntentSynchronizationService intentSynchronizer;
99
nosignal5fd282e2016-09-16 16:11:40 -0700100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected NetworkConfigService configService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100104 protected VplsConfigService vplsConfigService;
nosignal5fd282e2016-09-16 16:11:40 -0700105
Luca Prete9c2ee072016-02-16 11:00:44 -0800106 private final HostListener hostListener = new InternalHostListener();
107
Luca Prete092e8952016-10-26 16:25:56 +0200108 private final InternalInterfaceListener interfaceListener =
109 new InternalInterfaceListener();
Luca Pretea8854822016-04-26 16:30:55 -0700110
nosignal5fd282e2016-09-16 16:11:40 -0700111 private final InternalNetworkConfigListener configListener =
112 new InternalNetworkConfigListener();
113
Luca Prete9c2ee072016-02-16 11:00:44 -0800114 private IntentInstaller intentInstaller;
115
116 private ApplicationId appId;
117
Yi Tseng28767f02016-09-13 04:27:20 -0700118
Luca Prete9c2ee072016-02-16 11:00:44 -0800119 @Activate
120 public void activate() {
121 appId = coreService.registerApplication(VPLS_APP);
122
123 intentInstaller = new IntentInstaller(appId,
124 intentService,
125 intentSynchronizer);
126
Luca Prete2705d662016-04-29 15:30:23 -0700127 applicationService.registerDeactivateHook(appId, () -> {
128 intentSynchronizer.removeIntentsByAppId(appId);
129 });
Luca Prete9c2ee072016-02-16 11:00:44 -0800130
131 hostService.addListener(hostListener);
Luca Pretea8854822016-04-26 16:30:55 -0700132 interfaceService.addListener(interfaceListener);
nosignal5fd282e2016-09-16 16:11:40 -0700133 configService.addListener(configListener);
Luca Prete9c2ee072016-02-16 11:00:44 -0800134
nosignal5fd282e2016-09-16 16:11:40 -0700135 setupConnectivity(false);
Luca Prete9c2ee072016-02-16 11:00:44 -0800136
Luca Pretec21c6e62016-09-22 14:52:21 -0700137 log.info("Activated");
Luca Prete9c2ee072016-02-16 11:00:44 -0800138 }
139
140 @Deactivate
141 public void deactivate() {
nosignal5fd282e2016-09-16 16:11:40 -0700142 configService.removeListener(configListener);
Yi Tseng28767f02016-09-13 04:27:20 -0700143 intentSynchronizer.removeIntentsByAppId(appId);
Luca Pretec21c6e62016-09-22 14:52:21 -0700144 log.info("Deactivated");
Luca Prete9c2ee072016-02-16 11:00:44 -0800145 }
146
nosignal5fd282e2016-09-16 16:11:40 -0700147 /**
148 * Sets up connectivity for all VPLSs.
149 *
150 * @param isNetworkConfigEvent true if this function is triggered
151 * by NetworkConfigEvent; false otherwise
152 */
153 private void setupConnectivity(boolean isNetworkConfigEvent) {
154 SetMultimap<String, Interface> networkInterfaces =
Luca Prete092e8952016-10-26 16:25:56 +0200155 vplsConfigService.ifacesByVplsName();
Luca Prete9c2ee072016-02-16 11:00:44 -0800156
nosignal5fd282e2016-09-16 16:11:40 -0700157 Set<String> vplsAffectedByApi =
Luca Prete092e8952016-10-26 16:25:56 +0200158 new HashSet<>(vplsConfigService.vplsAffectedByApi());
Luca Prete9c2ee072016-02-16 11:00:44 -0800159
nosignal5fd282e2016-09-16 16:11:40 -0700160 if (isNetworkConfigEvent && vplsAffectedByApi.isEmpty()) {
Luca Prete092e8952016-10-26 16:25:56 +0200161 vplsAffectedByApi.addAll(vplsConfigService.vplsNamesOld());
nosignal5fd282e2016-09-16 16:11:40 -0700162 }
Yi Tseng28767f02016-09-13 04:27:20 -0700163
Luca Prete092e8952016-10-26 16:25:56 +0200164 networkInterfaces.asMap().forEach((vplsName, interfaces) -> {
nosignal5fd282e2016-09-16 16:11:40 -0700165 Set<Host> hosts = Sets.newHashSet();
166 interfaces.forEach(intf -> {
167 // Add hosts that belongs to the specific VPLS
168 hostService.getConnectedHosts(intf.connectPoint())
169 .stream()
170 .filter(host -> host.vlan().equals(intf.vlan()))
171 .forEach(hosts::add);
172 });
173
Luca Prete092e8952016-10-26 16:25:56 +0200174 EncapsulationType encap =
175 vplsConfigService.encap(vplsName);
176
177 setupConnectivity(vplsName, interfaces, hosts, encap,
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100178 vplsAffectedByApi.contains(vplsName));
Luca Prete092e8952016-10-26 16:25:56 +0200179 vplsAffectedByApi.remove(vplsName);
nosignal5fd282e2016-09-16 16:11:40 -0700180 });
181
182 if (!vplsAffectedByApi.isEmpty()) {
Luca Prete092e8952016-10-26 16:25:56 +0200183 for (String vplsName : vplsAffectedByApi) {
184 withdrawIntents(vplsName, Lists.newArrayList());
nosignal5fd282e2016-09-16 16:11:40 -0700185 }
186 }
Luca Prete9c2ee072016-02-16 11:00:44 -0800187 }
188
189 /**
nosignal5fd282e2016-09-16 16:11:40 -0700190 * Sets up connectivity for specific VPLS.
Luca Prete9c2ee072016-02-16 11:00:44 -0800191 *
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100192 * @param vplsName the VPLS name
193 * @param interfaces the interfaces that belong to the VPLS
194 * @param hosts the hosts that belong to the VPLS
195 * @param encap the encapsulation type
nosignal5fd282e2016-09-16 16:11:40 -0700196 * @param affectedByApi true if this function is triggered from the APIs;
197 * false otherwise
Luca Prete9c2ee072016-02-16 11:00:44 -0800198 */
Luca Prete092e8952016-10-26 16:25:56 +0200199 private void setupConnectivity(String vplsName,
nosignal5fd282e2016-09-16 16:11:40 -0700200 Collection<Interface> interfaces,
201 Set<Host> hosts,
Luca Prete092e8952016-10-26 16:25:56 +0200202 EncapsulationType encap,
nosignal5fd282e2016-09-16 16:11:40 -0700203 boolean affectedByApi) {
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100204
nosignal5fd282e2016-09-16 16:11:40 -0700205 List<Intent> intents = Lists.newArrayList();
206 List<Key> keys = Lists.newArrayList();
207 Set<FilteredConnectPoint> fcPoints = buildFCPoints(interfaces);
Luca Prete9c2ee072016-02-16 11:00:44 -0800208
nosignal5fd282e2016-09-16 16:11:40 -0700209 intents.addAll(buildBroadcastIntents(
Luca Prete092e8952016-10-26 16:25:56 +0200210 vplsName, fcPoints, encap, affectedByApi));
211 intents.addAll(buildUnicastIntents(
212 vplsName, hosts, fcPoints, encap, affectedByApi));
Luca Prete9c2ee072016-02-16 11:00:44 -0800213
nosignal5fd282e2016-09-16 16:11:40 -0700214 if (affectedByApi) {
215 intents.forEach(intent -> keys.add(intent.key()));
Luca Prete092e8952016-10-26 16:25:56 +0200216 withdrawIntents(vplsName, keys);
nosignal5fd282e2016-09-16 16:11:40 -0700217 }
218
219 intentInstaller.submitIntents(intents);
Luca Prete9c2ee072016-02-16 11:00:44 -0800220 }
221
222 /**
nosignal5fd282e2016-09-16 16:11:40 -0700223 * Withdraws intents belonging to a VPLS, given a VPLS name.
Luca Prete9c2ee072016-02-16 11:00:44 -0800224 *
Luca Prete092e8952016-10-26 16:25:56 +0200225 * @param vplsName the VPLS name
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100226 * @param keys the keys of the intents to be installed
Luca Prete9c2ee072016-02-16 11:00:44 -0800227 */
Luca Prete092e8952016-10-26 16:25:56 +0200228 private void withdrawIntents(String vplsName, List<Key> keys) {
nosignal5fd282e2016-09-16 16:11:40 -0700229 List<Intent> intents = Lists.newArrayList();
Luca Prete9c2ee072016-02-16 11:00:44 -0800230
Luca Prete092e8952016-10-26 16:25:56 +0200231 intentInstaller.getIntentsFromVpls(vplsName)
nosignal5fd282e2016-09-16 16:11:40 -0700232 .forEach(intent -> {
233 if (!keys.contains(intent.key())) {
234 intents.add(intent);
235 }
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100236 });
Luca Prete9c2ee072016-02-16 11:00:44 -0800237
nosignal5fd282e2016-09-16 16:11:40 -0700238 intentInstaller.withdrawIntents(intents);
Luca Prete9c2ee072016-02-16 11:00:44 -0800239 }
240
nosignal5fd282e2016-09-16 16:11:40 -0700241 /**
242 * Sets up broadcast intents between any given filtered connect point.
243 *
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100244 * @param vplsName the VPLS name
245 * @param fcPoints the set of filtered connect points
246 * @param encap the encapsulation type
nosignal5fd282e2016-09-16 16:11:40 -0700247 * @param affectedByApi true if the function triggered from APIs;
248 * false otherwise
249 * @return the set of broadcast intents
250 */
Luca Prete092e8952016-10-26 16:25:56 +0200251 private Set<Intent> buildBroadcastIntents(String vplsName,
nosignal5fd282e2016-09-16 16:11:40 -0700252 Set<FilteredConnectPoint> fcPoints,
Luca Prete092e8952016-10-26 16:25:56 +0200253 EncapsulationType encap,
nosignal5fd282e2016-09-16 16:11:40 -0700254 boolean affectedByApi) {
255 Set<Intent> intents = Sets.newHashSet();
256 fcPoints.forEach(point -> {
257 Set<FilteredConnectPoint> otherPoints =
258 fcPoints.stream()
259 .filter(fcp -> !fcp.equals(point))
260 .collect(Collectors.toSet());
261
262 Key brcKey = intentInstaller.buildKey(PREFIX_BROADCAST,
263 point.connectPoint(),
Luca Prete092e8952016-10-26 16:25:56 +0200264 vplsName,
nosignal5fd282e2016-09-16 16:11:40 -0700265 MacAddress.BROADCAST);
266
Luca Prete092e8952016-10-26 16:25:56 +0200267 if ((!intentInstaller.intentExists(brcKey) || affectedByApi)
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100268 && !otherPoints.isEmpty()) {
nosignal5fd282e2016-09-16 16:11:40 -0700269 intents.add(intentInstaller.buildBrcIntent(brcKey,
270 point,
Luca Prete092e8952016-10-26 16:25:56 +0200271 otherPoints,
272 encap));
Yi Tsengbf8b67e2016-09-01 15:02:11 +0800273 }
274 });
nosignal5fd282e2016-09-16 16:11:40 -0700275
276 return ImmutableSet.copyOf(intents);
277 }
278
279 /**
280 * Sets up unicast intents between any given filtered connect point.
281 *
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100282 * @param vplsName the VPLS name
283 * @param hosts the set of destination hosts
284 * @param fcPoints the set of filtered connect points
285 * @param encap the encapsulation type
nosignal5fd282e2016-09-16 16:11:40 -0700286 * @param affectedByApi true if the function triggered from APIs;
287 * false otherwise
288 * @return the set of unicast intents
289 */
Luca Prete092e8952016-10-26 16:25:56 +0200290 private Set<Intent> buildUnicastIntents(String vplsName,
nosignal5fd282e2016-09-16 16:11:40 -0700291 Set<Host> hosts,
292 Set<FilteredConnectPoint> fcPoints,
Luca Prete092e8952016-10-26 16:25:56 +0200293 EncapsulationType encap,
nosignal5fd282e2016-09-16 16:11:40 -0700294 boolean affectedByApi) {
295 Set<Intent> intents = Sets.newHashSet();
296 hosts.forEach(host -> {
297 FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
298
299 if (hostPoint == null) {
300 log.warn(HOST_FCP_NOT_FOUND, host);
301 return;
302 }
303
304 Set<FilteredConnectPoint> otherPoints =
305 fcPoints.stream()
306 .filter(fcp -> !fcp.equals(hostPoint))
307 .collect(Collectors.toSet());
308
309 Key uniKey = intentInstaller.buildKey(PREFIX_UNICAST,
310 host.location(),
Luca Prete092e8952016-10-26 16:25:56 +0200311 vplsName,
nosignal5fd282e2016-09-16 16:11:40 -0700312 host.mac());
313
314 if ((!intentInstaller.intentExists(uniKey) || affectedByApi) &&
315 !otherPoints.isEmpty()) {
316 intents.add(intentInstaller.buildUniIntent(uniKey,
317 otherPoints,
318 hostPoint,
Luca Prete092e8952016-10-26 16:25:56 +0200319 host,
320 encap));
nosignal5fd282e2016-09-16 16:11:40 -0700321 }
322 });
323
324 return ImmutableSet.copyOf(intents);
325 }
326
327 /**
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100328 * Returns the filtered connect point associated to a given host.
nosignal5fd282e2016-09-16 16:11:40 -0700329 *
330 * @param host the target host
331 * @param fcps the filtered connected points
332 * @return null if not found; the filtered connect point otherwise
333 */
334 private FilteredConnectPoint getHostPoint(Host host,
335 Set<FilteredConnectPoint> fcps) {
336 return fcps.stream()
337 .filter(fcp -> fcp.connectPoint().equals(host.location()))
338 .filter(fcp -> {
339 VlanIdCriterion vlanCriterion =
340 (VlanIdCriterion) fcp.trafficSelector().
341 getCriterion(Criterion.Type.VLAN_VID);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100342 return vlanCriterion == null ||
nosignal5fd282e2016-09-16 16:11:40 -0700343 vlanCriterion.vlanId().equals(host.vlan());
344 })
345 .findFirst()
346 .orElse(null);
347 }
348
349 /**
350 * Computes a set of filtered connect points from a list of given interfaces.
351 *
352 * @param interfaces the interfaces to compute
353 * @return the set of filtered connect points
354 */
355 private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
Luca Prete092e8952016-10-26 16:25:56 +0200356 // Build all filtered connected points in the VPLS
nosignal5fd282e2016-09-16 16:11:40 -0700357 return interfaces
358 .stream()
359 .map(intf -> {
360 TrafficSelector.Builder selectorBuilder =
361 DefaultTrafficSelector.builder();
nosignal5fd282e2016-09-16 16:11:40 -0700362 if (!intf.vlan().equals(VlanId.NONE)) {
363 selectorBuilder.matchVlanId(intf.vlan());
364 }
nosignal5fd282e2016-09-16 16:11:40 -0700365 return new FilteredConnectPoint(intf.connectPoint(),
366 selectorBuilder.build());
367 })
368 .collect(Collectors.toSet());
Luca Prete9c2ee072016-02-16 11:00:44 -0800369 }
370
371 /**
372 * Listener for host events.
373 */
nosignal5fd282e2016-09-16 16:11:40 -0700374 private class InternalHostListener implements HostListener {
Luca Prete9c2ee072016-02-16 11:00:44 -0800375 @Override
376 public void event(HostEvent event) {
nosignal5fd282e2016-09-16 16:11:40 -0700377 log.debug(HOST_EVENT, event);
Luca Prete9c2ee072016-02-16 11:00:44 -0800378 switch (event.type()) {
379 case HOST_ADDED:
380 case HOST_UPDATED:
381 case HOST_REMOVED:
nosignal5fd282e2016-09-16 16:11:40 -0700382 setupConnectivity(false);
Luca Prete9c2ee072016-02-16 11:00:44 -0800383 break;
nosignal5fd282e2016-09-16 16:11:40 -0700384
Luca Prete9c2ee072016-02-16 11:00:44 -0800385 default:
386 break;
387 }
388 }
389 }
Luca Pretea8854822016-04-26 16:30:55 -0700390
391 /**
392 * Listener for interface configuration events.
393 */
394 private class InternalInterfaceListener implements InterfaceListener {
395 @Override
396 public void event(InterfaceEvent event) {
nosignal5fd282e2016-09-16 16:11:40 -0700397 log.debug(INTF_CONF_EVENT, event);
Luca Pretea8854822016-04-26 16:30:55 -0700398 switch (event.type()) {
399 case INTERFACE_ADDED:
400 case INTERFACE_UPDATED:
401 case INTERFACE_REMOVED:
nosignal5fd282e2016-09-16 16:11:40 -0700402 setupConnectivity(false);
Luca Pretea8854822016-04-26 16:30:55 -0700403 break;
404 default:
405 break;
406 }
407 }
408 }
nosignal5fd282e2016-09-16 16:11:40 -0700409
410 /**
411 * Listener for VPLS configuration events.
412 */
413 private class InternalNetworkConfigListener implements NetworkConfigListener {
414 @Override
415 public void event(NetworkConfigEvent event) {
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100416 if (event.configClass() == VplsConfigService.CONFIG_CLASS) {
nosignal5fd282e2016-09-16 16:11:40 -0700417 log.debug(NET_CONF_EVENT, event.configClass());
418 switch (event.type()) {
419 case CONFIG_ADDED:
420 case CONFIG_UPDATED:
421 case CONFIG_REMOVED:
422 setupConnectivity(true);
423 break;
nosignal5fd282e2016-09-16 16:11:40 -0700424 default:
425 break;
426 }
427 }
428 }
429 }
Luca Prete9c2ee072016-02-16 11:00:44 -0800430}