blob: edfbfd0c61a0a845777316eef9a97faaa1ae6436 [file] [log] [blame]
Mohammad Shahid4c30ea32017-08-09 18:02:10 +05301/*
2 * Copyright 2017-present Open Networking Foundation
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 */
16
17package org.onosproject.evpnopenflow.manager.impl;
18
19import com.fasterxml.jackson.databind.JsonNode;
20import com.google.common.collect.Sets;
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053021import org.onlab.osgi.DefaultServiceDirectory;
22import org.onlab.packet.EthType;
23import org.onlab.packet.IpAddress;
24import org.onlab.packet.IpPrefix;
25import org.onlab.packet.MplsLabel;
26import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.evpnopenflow.manager.EvpnService;
29import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
30import org.onosproject.evpnopenflow.rsc.VpnInstance;
31import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
32import org.onosproject.evpnopenflow.rsc.VpnPort;
33import org.onosproject.evpnopenflow.rsc.VpnPortId;
34import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
35import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigEvent;
36import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigListener;
37import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
38import org.onosproject.evpnopenflow.rsc.vpninstance.VpnInstanceService;
39import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortEvent;
40import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortListener;
41import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
Ray Milkeya95193c2017-08-10 15:35:36 -070042import org.onosproject.evpnrouteservice.EvpnInstanceName;
43import org.onosproject.evpnrouteservice.EvpnInstanceNextHop;
44import org.onosproject.evpnrouteservice.EvpnInstancePrefix;
45import org.onosproject.evpnrouteservice.EvpnInstanceRoute;
46import org.onosproject.evpnrouteservice.EvpnNextHop;
47import org.onosproject.evpnrouteservice.EvpnRoute;
48import org.onosproject.evpnrouteservice.EvpnRoute.Source;
49import org.onosproject.evpnrouteservice.EvpnRouteAdminService;
50import org.onosproject.evpnrouteservice.EvpnRouteEvent;
51import org.onosproject.evpnrouteservice.EvpnRouteListener;
52import org.onosproject.evpnrouteservice.EvpnRouteService;
53import org.onosproject.evpnrouteservice.EvpnRouteSet;
54import org.onosproject.evpnrouteservice.EvpnRouteStore;
55import org.onosproject.evpnrouteservice.Label;
56import org.onosproject.evpnrouteservice.RouteDistinguisher;
57import org.onosproject.evpnrouteservice.VpnRouteTarget;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070058import org.onosproject.gluon.rsc.GluonConfig;
59import org.onosproject.incubator.net.resource.label.LabelResource;
60import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
61import org.onosproject.incubator.net.resource.label.LabelResourceId;
62import org.onosproject.incubator.net.resource.label.LabelResourceService;
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053063import org.onosproject.mastership.MastershipService;
64import org.onosproject.net.AnnotationKeys;
65import org.onosproject.net.Device;
66import org.onosproject.net.DeviceId;
67import org.onosproject.net.Host;
68import org.onosproject.net.Port;
69import org.onosproject.net.PortNumber;
70import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
71import org.onosproject.net.config.NetworkConfigEvent;
72import org.onosproject.net.config.NetworkConfigListener;
73import org.onosproject.net.config.NetworkConfigService;
74import org.onosproject.net.device.DeviceService;
75import org.onosproject.net.driver.DriverHandler;
76import org.onosproject.net.driver.DriverService;
77import org.onosproject.net.flow.DefaultTrafficSelector;
78import org.onosproject.net.flow.DefaultTrafficTreatment;
79import org.onosproject.net.flow.TrafficSelector;
80import org.onosproject.net.flow.TrafficTreatment;
81import org.onosproject.net.flow.instructions.ExtensionTreatment;
82import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
83import org.onosproject.net.flowobjective.DefaultForwardingObjective;
84import org.onosproject.net.flowobjective.FlowObjectiveService;
85import org.onosproject.net.flowobjective.ForwardingObjective;
86import org.onosproject.net.flowobjective.Objective;
87import org.onosproject.net.flowobjective.Objective.Operation;
88import org.onosproject.net.host.HostEvent;
89import org.onosproject.net.host.HostListener;
90import org.onosproject.net.host.HostService;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070091import org.osgi.service.component.annotations.Activate;
92import org.osgi.service.component.annotations.Component;
93import org.osgi.service.component.annotations.Deactivate;
94import org.osgi.service.component.annotations.Reference;
95import org.osgi.service.component.annotations.ReferenceCardinality;
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053096import org.slf4j.Logger;
97
98import java.util.ArrayList;
99import java.util.Collection;
100import java.util.HashSet;
101import java.util.LinkedList;
102import java.util.List;
103import java.util.Set;
104
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530105import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
106import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ARP_PRIORITY;
107import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ARP_RESPONSE;
108import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BASEPORT;
109import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BGP_EVPN_ROUTE_DELETE_START;
110import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BGP_EVPN_ROUTE_UPDATE_START;
111import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BOTH;
112import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANNOT_FIND_TUNNEL_PORT_DEVICE;
113import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_CONTROLLER_DEVICE;
114import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_VPN_INSTANCE;
115import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_VPN_PORT;
116import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
117import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_OPENFLOW_START;
118import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_OPENFLOW_STOP;
119import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_EXTCOMMUNITY;
120import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FAILED_TO_SET_TUNNEL_DST;
121import static org.onosproject.evpnopenflow.rsc.EvpnConstants.GET_PRIVATE_LABEL;
122import static org.onosproject.evpnopenflow.rsc.EvpnConstants.HOST_DETECT;
123import static org.onosproject.evpnopenflow.rsc.EvpnConstants.HOST_VANISHED;
124import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IFACEID;
125import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IFACEID_OF_HOST_IS_NULL;
126import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_EXTCOMMUNITY;
127import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_EVENT_RECEIVED;
128import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_ROUTE_TARGET_TYPE;
129import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_TARGET_RECEIVED;
130import static org.onosproject.evpnopenflow.rsc.EvpnConstants.MPLS_OUT_FLOWS;
131import static org.onosproject.evpnopenflow.rsc.EvpnConstants.NETWORK_CONFIG_EVENT_IS_RECEIVED;
132import static org.onosproject.evpnopenflow.rsc.EvpnConstants.NOT_MASTER_FOR_SPECIFIC_DEVICE;
133import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RELEASE_LABEL_FAILED;
134import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_ADD_ARP_RULES;
135import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_REMOVE_ARP_RULES;
136import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
137import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
138import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SWITCH_CHANNEL_ID;
139import static org.onosproject.evpnopenflow.rsc.EvpnConstants.TUNNEL_DST;
140import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
141import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_TARGET;
142import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_TARGET;
143import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_BIND;
144import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_TARGET;
145import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_UNBIND;
146import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VXLAN;
147import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
148import static org.slf4j.LoggerFactory.getLogger;
149
150/**
151 * Implementation of the EVPN service.
152 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700153@Component(immediate = true, service = EvpnService.class)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530154public class EvpnManager implements EvpnService {
155 private final Logger log = getLogger(getClass());
156 private static final EthType.EtherType ARP_TYPE = EthType.EtherType.ARP;
157
158 protected ApplicationId appId;
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700159 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530160 protected HostService hostService;
161
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700162 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530163 protected CoreService coreService;
164
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700165 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530166 protected EvpnRouteService evpnRouteService;
167
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700168 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530169 protected EvpnRouteStore evpnRouteStore;
170
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700171 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530172 protected DeviceService deviceService;
173
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700174 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530175 protected EvpnRouteAdminService evpnRouteAdminService;
176
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700177 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530178 protected MastershipService mastershipService;
179
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700180 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530181 protected LabelResourceAdminService labelAdminService;
182
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700183 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530184 protected LabelResourceService labelService;
185
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700186 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530187 protected VpnInstanceService vpnInstanceService;
188
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700189 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530190 protected FlowObjectiveService flowObjectiveService;
191
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700192 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530193 protected DriverService driverService;
194
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700195 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530196 protected VpnPortService vpnPortService;
197
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700198 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530199 protected VpnAfConfigService vpnAfConfigService;
200
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700201 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530202 protected NetworkConfigService configService;
203
204 public Set<EvpnInstanceRoute> evpnInstanceRoutes = new HashSet<>();
205 private final HostListener hostListener = new InnerHostListener();
206 private final VpnPortListener vpnPortListner = new InnerVpnPortListener();
207 private final VpnAfConfigListener vpnAfConfigListener = new
208 InnerVpnAfConfigListener();
209 private final InternalRouteEventListener routeListener = new
210 InternalRouteEventListener();
211
212 private final NetworkConfigListener configListener = new
213 InternalNetworkConfigListener();
214
215 @Activate
216 public void activate() {
217 appId = coreService.registerApplication(APP_ID);
218 hostService.addListener(hostListener);
219 vpnPortService.addListener(vpnPortListner);
220 vpnAfConfigService.addListener(vpnAfConfigListener);
221 configService.addListener(configListener);
222 evpnRouteService.addListener(routeListener);
223
224 labelAdminService
225 .createGlobalPool(LabelResourceId.labelResourceId(1),
226 LabelResourceId.labelResourceId(1000));
227 log.info(EVPN_OPENFLOW_START);
228 }
229
230 @Deactivate
231 public void deactivate() {
232 hostService.removeListener(hostListener);
233 vpnPortService.removeListener(vpnPortListner);
234 vpnAfConfigService.removeListener(vpnAfConfigListener);
235 configService.removeListener(configListener);
236 log.info(EVPN_OPENFLOW_STOP);
237 }
238
239 @Override
240 public void onBgpEvpnRouteUpdate(EvpnRoute route) {
241 if (EvpnRoute.Source.LOCAL.equals(route.source())) {
242 return;
243 }
244 log.info(BGP_EVPN_ROUTE_UPDATE_START, route);
245 // deal with public route and transfer to private route
246 if (vpnInstanceService.getInstances().isEmpty()) {
247 log.info("unable to get instnaces from vpninstance");
248 return;
249 }
250
251 vpnInstanceService.getInstances().forEach(vpnInstance -> {
252 log.info("got instnaces from vpninstance but not entered here");
253 List<VpnRouteTarget> vpnImportRouteRt = new
254 LinkedList<>(vpnInstance.getImportRouteTargets());
255 List<VpnRouteTarget> expRt = route.exportRouteTarget();
256 List<VpnRouteTarget> similar = new LinkedList<>(expRt);
257 similar.retainAll(vpnImportRouteRt);
258
259 if (!similar.isEmpty()) {
260 EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
261 .evpnPrefix(route.prefixMac(), route.prefixIp());
262
263 EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
264 .evpnNextHop(route.ipNextHop(), route.label());
265
266 EvpnInstanceRoute evpnPrivateRoute = new
267 EvpnInstanceRoute(vpnInstance.vpnInstanceName(),
268 route.routeDistinguisher(),
269 vpnImportRouteRt,
270 route.exportRouteTarget(),
271 evpnPrefix,
272 evpnNextHop,
273 route.prefixIp(),
274 route.ipNextHop(),
275 route.label());
276
277 //update route in route subsystem
278 //TODO: added by shahid
279 evpnInstanceRoutes.add(evpnPrivateRoute);
280
281 }
282 });
283
284 deviceService.getAvailableDevices(Device.Type.SWITCH)
285 .forEach(device -> {
286 log.info("switch device is found");
287 Set<Host> hosts = getHostsByVpn(device, route);
288 for (Host h : hosts) {
289 addArpFlows(device.id(),
290 route,
291 Objective.Operation.ADD,
292 h);
293 ForwardingObjective.Builder objective =
294 getMplsOutBuilder(device.id(),
295 route,
296 h);
297 log.info(MPLS_OUT_FLOWS, h);
298 flowObjectiveService.forward(device.id(),
299 objective.add());
300 }
301 });
302 log.info("no switch device is found");
303 }
304
305 @Override
306 public void onBgpEvpnRouteDelete(EvpnRoute route) {
307 if (EvpnRoute.Source.LOCAL.equals(route.source())) {
308 return;
309 }
310 log.info(BGP_EVPN_ROUTE_DELETE_START, route);
311 // deal with public route deleted and transfer to private route
312 vpnInstanceService.getInstances().forEach(vpnInstance -> {
313 List<VpnRouteTarget> vpnRouteRt = new
314 LinkedList<>(vpnInstance.getImportRouteTargets());
315 List<VpnRouteTarget> localRt = route.exportRouteTarget();
316 List<VpnRouteTarget> similar = new LinkedList<>(localRt);
317 similar.retainAll(vpnRouteRt);
318
319 if (!similar.isEmpty()) {
320 EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
321 .evpnPrefix(route.prefixMac(), route.prefixIp());
322
323 EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
324 .evpnNextHop(route.ipNextHop(), route.label());
325
326 EvpnInstanceRoute evpnPrivateRoute = new
327 EvpnInstanceRoute(vpnInstance.vpnInstanceName(),
328 route.routeDistinguisher(),
329 vpnRouteRt,
330 route.exportRouteTarget(),
331 evpnPrefix,
332 evpnNextHop,
333 route.prefixIp(),
334 route.ipNextHop(),
335 route.label());
336 //TODO: Added by Shahid
337 //evpnRouteAdminService.withdraw(Sets.newHashSet
338 // (evpnPrivateRoute));
339
340 }
341 });
342 deviceService.getAvailableDevices(Device.Type.SWITCH)
343 .forEach(device -> {
344 Set<Host> hosts = getHostsByVpn(device, route);
345 for (Host h : hosts) {
346 addArpFlows(device.id(),
347 route,
348 Objective.Operation.REMOVE,
349 h);
350 ForwardingObjective.Builder objective
351 = getMplsOutBuilder(device.id(),
352 route,
353 h);
354 flowObjectiveService.forward(device.id(),
355 objective.remove());
356 }
357 });
358 }
359
360 private void addArpFlows(DeviceId deviceId,
361 EvpnRoute route,
362 Operation type,
363 Host host) {
364 DriverHandler handler = driverService.createHandler(deviceId);
365 TrafficSelector selector = DefaultTrafficSelector.builder()
366 .matchEthType(ARP_TYPE.ethType().toShort())
367 .matchArpTpa(route.prefixIp().address().getIp4Address())
368 .matchInPort(host.location().port()).build();
369
370 ExtensionTreatmentResolver resolver = handler
371 .behaviour(ExtensionTreatmentResolver.class);
372 ExtensionTreatment ethSrcToDst = resolver
373 .getExtensionInstruction(ExtensionTreatmentType
374 .ExtensionTreatmentTypes
375 .NICIRA_MOV_ETH_SRC_TO_DST
376 .type());
377 ExtensionTreatment arpShaToTha = resolver
378 .getExtensionInstruction(ExtensionTreatmentType
379 .ExtensionTreatmentTypes
380 .NICIRA_MOV_ARP_SHA_TO_THA
381 .type());
382 ExtensionTreatment arpSpaToTpa = resolver
383 .getExtensionInstruction(ExtensionTreatmentType
384 .ExtensionTreatmentTypes
385 .NICIRA_MOV_ARP_SPA_TO_TPA
386 .type());
387 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
388 .extension(ethSrcToDst, deviceId).setEthSrc(route.prefixMac())
389 .setArpOp(ARP_RESPONSE).extension(arpShaToTha, deviceId)
390 .extension(arpSpaToTpa, deviceId).setArpSha(route.prefixMac())
391 .setArpSpa(route.prefixIp().address().getIp4Address())
392 .setOutput(PortNumber.IN_PORT)
393 .build();
394
395 ForwardingObjective.Builder objective = DefaultForwardingObjective
396 .builder().withTreatment(treatment).withSelector(selector)
397 .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
398 .withPriority(ARP_PRIORITY);
399 if (type.equals(Objective.Operation.ADD)) {
400 log.info(ROUTE_ADD_ARP_RULES);
401 flowObjectiveService.forward(deviceId, objective.add());
402 } else {
403 log.info(ROUTE_REMOVE_ARP_RULES);
404 flowObjectiveService.forward(deviceId, objective.remove());
405 }
406 }
407
408 private Set<Host> getHostsByVpn(Device device, EvpnRoute route) {
409 Set<Host> vpnHosts = Sets.newHashSet();
410 Set<Host> hosts = hostService.getConnectedHosts(device.id());
411 for (Host h : hosts) {
412 String ifaceId = h.annotations().value(IFACEID);
413 if (!vpnPortService.exists(VpnPortId.vpnPortId(ifaceId))) {
414 continue;
415 }
416
417 VpnPort vpnPort = vpnPortService
418 .getPort(VpnPortId.vpnPortId(ifaceId));
419 VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
420
421 VpnInstance vpnInstance = vpnInstanceService
422 .getInstance(vpnInstanceId);
423
424 List<VpnRouteTarget> expRt = route.exportRouteTarget();
425 List<VpnRouteTarget> similar = new LinkedList<>(expRt);
426 similar.retainAll(vpnInstance.getImportRouteTargets());
Ray Milkeyc108a6b2017-08-23 15:23:50 -0700427 //TODO: currently checking for RT comparison.
428 //TODO: Need to check about RD comparison is really required.
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530429 //if (route.routeDistinguisher()
430 //.equals(vpnInstance.routeDistinguisher())) {
431 if (!similar.isEmpty()) {
432 vpnHosts.add(h);
433 }
434 }
435 return vpnHosts;
436 }
437
438 private ForwardingObjective.Builder getMplsOutBuilder(DeviceId deviceId,
439 EvpnRoute route,
440 Host h) {
441 DriverHandler handler = driverService.createHandler(deviceId);
442 ExtensionTreatmentResolver resolver = handler
443 .behaviour(ExtensionTreatmentResolver.class);
444 ExtensionTreatment treatment = resolver
445 .getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
446 try {
447 treatment.setPropertyValue(TUNNEL_DST, route.ipNextHop());
448 } catch (Exception e) {
449 log.error(FAILED_TO_SET_TUNNEL_DST, deviceId);
450 }
451 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
452 builder.extension(treatment, deviceId);
453 TrafficSelector selector = DefaultTrafficSelector.builder()
454 .matchInPort(h.location().port()).matchEthSrc(h.mac())
455 .matchEthDst(route.prefixMac()).build();
456
457 TrafficTreatment build = builder.pushMpls()
458 .setMpls(MplsLabel.mplsLabel(route.label().getLabel()))
459 .setOutput(getTunnlePort(deviceId)).build();
460
461 return DefaultForwardingObjective
462 .builder().withTreatment(build).withSelector(selector)
463 .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
464 .withPriority(60000);
465
466 }
467
468 private ForwardingObjective.Builder getMplsInBuilder(DeviceId deviceId,
469 Host host,
470 Label label) {
471 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
472 TrafficSelector selector = DefaultTrafficSelector.builder()
473 .matchInPort(getTunnlePort(deviceId))
474 .matchEthType(EthType.EtherType.MPLS_UNICAST.ethType()
475 .toShort())
476 .matchMplsBos(true)
477 .matchMplsLabel(MplsLabel.mplsLabel(label.getLabel())).build();
478 TrafficTreatment treatment = builder.popMpls(EthType
479 .EtherType
480 .IPV4.ethType())
481 .setOutput(host.location().port()).build();
482 return DefaultForwardingObjective
483 .builder().withTreatment(treatment).withSelector(selector)
484 .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
485 .withPriority(60000);
486 }
487
488 /**
489 * Get local tunnel ports.
490 *
491 * @param ports Iterable of Port
492 * @return Collection of PortNumber
493 */
494 private Collection<PortNumber> getLocalTunnelPorts(Iterable<Port>
495 ports) {
496 Collection<PortNumber> localTunnelPorts = new ArrayList<>();
497 if (ports != null) {
498 log.info("port value is not null {}", ports);
499 Sets.newHashSet(ports).stream()
500 .filter(p -> !p.number().equals(PortNumber.LOCAL))
501 .forEach(p -> {
502 log.info("number is not matched but no vxlan port");
503 if (p.annotations().value(AnnotationKeys.PORT_NAME)
504 .startsWith(VXLAN)) {
505 localTunnelPorts.add(p.number());
506 }
507 });
508 }
509 return localTunnelPorts;
510 }
511
512 private PortNumber getTunnlePort(DeviceId deviceId) {
513 Iterable<Port> ports = deviceService.getPorts(deviceId);
514 Collection<PortNumber> localTunnelPorts = getLocalTunnelPorts(ports);
515 if (localTunnelPorts.isEmpty()) {
516 log.error(CANNOT_FIND_TUNNEL_PORT_DEVICE, deviceId);
517 return null;
518 }
519 return localTunnelPorts.iterator().next();
520 }
521
522 private void setFlows(DeviceId deviceId, Host host, Label label,
523 List<VpnRouteTarget> rtImport,
524 Operation type) {
525 log.info("Set the flows to OVS");
526 ForwardingObjective.Builder objective = getMplsInBuilder(deviceId,
527 host,
528 label);
529 if (type.equals(Objective.Operation.ADD)) {
530 flowObjectiveService.forward(deviceId, objective.add());
531 } else {
532 flowObjectiveService.forward(deviceId, objective.remove());
533 }
534
535 // download remote flows if and only routes are present.
536 evpnRouteStore.getRouteTables().forEach(routeTableId -> {
537 Collection<EvpnRouteSet> routes
538 = evpnRouteStore.getRoutes(routeTableId);
539 if (routes != null) {
540 routes.forEach(route -> {
541 Collection<EvpnRoute> evpnRoutes = route.routes();
542 for (EvpnRoute evpnRoute : evpnRoutes) {
543 EvpnRoute evpnRouteTem = evpnRoute;
544 Set<Host> hostByMac = hostService
545 .getHostsByMac(evpnRouteTem
546 .prefixMac());
547
548 if (!hostByMac.isEmpty()
549 || (!(compareLists(rtImport, evpnRouteTem
550 .exportRouteTarget())))) {
551 log.info("Route target import/export is not matched");
552 continue;
553 }
554 log.info("Set the ARP flows");
555 addArpFlows(deviceId, evpnRouteTem, type, host);
556 ForwardingObjective.Builder build = getMplsOutBuilder(deviceId,
557 evpnRouteTem,
558 host);
559 log.info("Set the MPLS flows");
560 if (type.equals(Objective.Operation.ADD)) {
561 flowObjectiveService.forward(deviceId, build.add());
562 } else {
563 flowObjectiveService.forward(deviceId, build.remove());
564 }
565 }
566 });
567 }
568 });
569 }
570
571 /**
572 * comparison for tow lists.
573 *
574 * @param list1 import list
575 * @param list2 export list
576 * @return true or false
577 */
578 public static boolean compareLists(List<VpnRouteTarget> list1,
579 List<VpnRouteTarget> list2) {
580 if (list1 == null && list2 == null) {
581 return true;
582 }
583
584 if (list1 != null && list2 != null) {
585 if (list1.size() == list2.size()) {
586 for (VpnRouteTarget li1Long : list1) {
587 boolean isEqual = false;
588 for (VpnRouteTarget li2Long : list2) {
589 if (li1Long.equals(li2Long)) {
590 isEqual = true;
591 break;
592 }
593 }
594 if (!isEqual) {
595 return false;
596 }
597 }
598 } else {
599 return false;
600 }
601 } else {
602 return false;
603 }
604 return true;
605 }
606
607 @Override
608 public void onHostDetected(Host host) {
609 log.info(HOST_DETECT, host);
610 DeviceId deviceId = host.location().deviceId();
611 if (!mastershipService.isLocalMaster(deviceId)) {
612 log.info(NOT_MASTER_FOR_SPECIFIC_DEVICE);
613 return;
614 }
615
616 String ifaceId = host.annotations().value(IFACEID);
617 if (ifaceId == null) {
618 log.error(IFACEID_OF_HOST_IS_NULL);
619 return;
620 }
621 VpnPortId vpnPortId = VpnPortId.vpnPortId(ifaceId);
622 // Get VPN port id from EVPN app store
623 if (!vpnPortService.exists(vpnPortId)) {
624 log.info(CANT_FIND_VPN_PORT, ifaceId);
625 return;
626 }
627
628 VpnPort vpnPort = vpnPortService.getPort(vpnPortId);
629 VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
630 if (!vpnInstanceService.exists(vpnInstanceId)) {
631 log.info(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
632 return;
633 }
634
635 Label privateLabel = applyLabel();
636 // create private route and get label
637 setPrivateRoute(host, vpnInstanceId, privateLabel,
638 Objective.Operation.ADD);
639 VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
640
641 List<VpnRouteTarget> rtImport
642 = new LinkedList<>(vpnInstance.getImportRouteTargets());
643 List<VpnRouteTarget> rtExport
644 = new LinkedList<>(vpnInstance.getExportRouteTargets());
645 //download flows
646 setFlows(deviceId, host, privateLabel, rtImport,
647 Objective.Operation.ADD);
648 }
649
650 /**
651 * update or withdraw evpn route from route admin service.
652 *
653 * @param host host
654 * @param vpnInstanceId vpn instance id
655 * @param privateLabel private label
656 * @param type operation type
657 */
658 private void setPrivateRoute(Host host, VpnInstanceId vpnInstanceId,
659 Label privateLabel,
660 Operation type) {
661 DeviceId deviceId = host.location().deviceId();
662 Device device = deviceService.getDevice(deviceId);
663 VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
664 RouteDistinguisher rd = vpnInstance.routeDistinguisher();
665 Set<VpnRouteTarget> importRouteTargets
666 = vpnInstance.getImportRouteTargets();
667 Set<VpnRouteTarget> exportRouteTargets
668 = vpnInstance.getExportRouteTargets();
669 EvpnInstanceName instanceName = vpnInstance.vpnInstanceName();
670 String url = device.annotations().value(SWITCH_CHANNEL_ID);
671 String controllerIp = url.substring(0, url.lastIndexOf(":"));
672
673 if (controllerIp == null) {
674 log.error(CANT_FIND_CONTROLLER_DEVICE, device.id().toString());
675 return;
676 }
677 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
678 // create private route
679 EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
680 .evpnNextHop(ipAddress, privateLabel);
681 EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
682 .evpnPrefix(host.mac(), IpPrefix.valueOf(host.ipAddresses()
683 .iterator()
684 .next()
685 .getIp4Address(), 32));
686 EvpnInstanceRoute evpnPrivateRoute
687 = new EvpnInstanceRoute(instanceName,
688 rd,
689 new LinkedList<>(importRouteTargets),
690 new LinkedList<>(exportRouteTargets),
691 evpnPrefix,
692 evpnNextHop,
693 IpPrefix.valueOf(host.ipAddresses()
694 .iterator()
695 .next()
696 .getIp4Address(), 32),
697 ipAddress,
698 privateLabel);
699
700 // change to public route
701 EvpnRoute evpnRoute
702 = new EvpnRoute(Source.LOCAL,
703 host.mac(),
704 IpPrefix.valueOf(host.ipAddresses()
705 .iterator()
706 .next()
707 .getIp4Address(), 32),
708 ipAddress,
709 rd,
710 new LinkedList<>(importRouteTargets),
711 new LinkedList<>(exportRouteTargets),
712 privateLabel);
713 if (type.equals(Objective.Operation.ADD)) {
714 //evpnRouteAdminService.update(Sets.newHashSet(evpnPrivateRoute));
715 evpnInstanceRoutes.add(evpnPrivateRoute);
716 evpnRouteAdminService.update(Sets.newHashSet(evpnRoute));
717
718 } else {
719 //evpnRouteAdminService.withdraw(Sets.newHashSet(evpnPrivateRoute));
720 evpnInstanceRoutes.remove(evpnPrivateRoute);
721 evpnRouteAdminService.withdraw(Sets.newHashSet(evpnRoute));
722 }
723 }
724
725 /**
726 * Generate the label for evpn route from global pool.
727 */
728 private Label applyLabel() {
729 Collection<LabelResource> privateLabels = labelService
730 .applyFromGlobalPool(1);
731 Label privateLabel = Label.label(0);
732 if (!privateLabels.isEmpty()) {
733 privateLabel = Label.label(Integer.parseInt(
734 privateLabels.iterator().next()
735 .labelResourceId().toString()));
736 }
737 log.info(GET_PRIVATE_LABEL, privateLabel);
738 return privateLabel;
739 }
740
741 @Override
742 public void onHostVanished(Host host) {
743 log.info(HOST_VANISHED, host);
744 DeviceId deviceId = host.location().deviceId();
745 if (!mastershipService.isLocalMaster(deviceId)) {
746 return;
747 }
748 String ifaceId = host.annotations().value(IFACEID);
749 if (ifaceId == null) {
750 log.error(IFACEID_OF_HOST_IS_NULL);
751 return;
752 }
753 // Get info from Gluon Shim
754 VpnPort vpnPort = vpnPortService.getPort(VpnPortId.vpnPortId(ifaceId));
755 VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
756 if (!vpnInstanceService.exists(vpnInstanceId)) {
757 log.info(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
758 return;
759 }
760 VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
761
762 Label label = releaseLabel(vpnInstance, host);
763 // create private route and get label
764 setPrivateRoute(host, vpnInstanceId, label, Objective.Operation.REMOVE);
765 // download flows
766 List<VpnRouteTarget> rtImport
767 = new LinkedList<>(vpnInstance.getImportRouteTargets());
768 List<VpnRouteTarget> rtExport
769 = new LinkedList<>(vpnInstance.getExportRouteTargets());
770 setFlows(deviceId, host, label, rtImport,
771 Objective.Operation.REMOVE);
772 }
773
774 /**
775 * Release the label from the evpn route.
776 *
777 * @param vpnInstance vpn instance
778 * @param host host
779 */
780 private Label releaseLabel(VpnInstance vpnInstance, Host host) {
781 EvpnInstanceName instanceName = vpnInstance.vpnInstanceName();
782
783 //Get all vpn-instance routes and check for label.
784 Label label = null;
785 for (EvpnInstanceRoute evpnInstanceRoute : evpnInstanceRoutes) {
786 if (evpnInstanceRoute.evpnInstanceName().equals(instanceName)) {
787 label = evpnInstanceRoute.getLabel();
788 // delete private route and get label ,change to public route
789 boolean isRelease
790 = labelService
791 .releaseToGlobalPool(
792 Sets.newHashSet(
793 LabelResourceId
794 .labelResourceId(label.getLabel())));
795 if (!isRelease) {
796 log.error(RELEASE_LABEL_FAILED, label.getLabel());
797 }
798 break;
799 }
800 }
801 return label;
802 }
803
804 private class InternalRouteEventListener implements EvpnRouteListener {
805
806 @Override
807 public void event(EvpnRouteEvent event) {
Ray Milkeyef310052018-02-06 08:58:51 -0800808 if (event.subject() != null) {
809 EvpnRoute route = (EvpnRoute) event.subject();
810 if (EvpnRouteEvent.Type.ROUTE_ADDED == event.type()) {
811 onBgpEvpnRouteUpdate(route);
812 } else if (EvpnRouteEvent.Type.ROUTE_REMOVED == event.type()) {
813 onBgpEvpnRouteDelete(route);
814 }
815 } else {
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530816 return;
817 }
Mohammad Shahid4c30ea32017-08-09 18:02:10 +0530818 }
819 }
820
821 private class InnerHostListener implements HostListener {
822
823 @Override
824 public void event(HostEvent event) {
825 Host host = event.subject();
826 if (HostEvent.Type.HOST_ADDED == event.type()) {
827 onHostDetected(host);
828 } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
829 onHostVanished(host);
830 }
831 }
832
833 }
834
835 private class InnerVpnPortListener implements VpnPortListener {
836
837 @Override
838 public void event(VpnPortEvent event) {
839 VpnPort vpnPort = event.subject();
840 if (VpnPortEvent.Type.VPN_PORT_DELETE == event.type()) {
841 onVpnPortDelete(vpnPort);
842 } else if (VpnPortEvent.Type.VPN_PORT_SET == event.type()) {
843 onVpnPortSet(vpnPort);
844 }
845 }
846 }
847
848 @Override
849 public void onVpnPortDelete(VpnPort vpnPort) {
850 // delete the flows of this vpn
851 hostService.getHosts().forEach(host -> {
852 VpnPortId vpnPortId = vpnPort.id();
853 VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
854 if (!vpnInstanceService.exists(vpnInstanceId)) {
855 log.error(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
856 return;
857 }
858 VpnInstance vpnInstance = vpnInstanceService
859 .getInstance(vpnInstanceId);
860 List<VpnRouteTarget> rtImport
861 = new LinkedList<>(vpnInstance.getImportRouteTargets());
862 List<VpnRouteTarget> rtExport
863 = new LinkedList<>(vpnInstance.getExportRouteTargets());
864
865 if (vpnPortId.vpnPortId()
866 .equals(host.annotations().value(IFACEID))) {
867 log.info(VPN_PORT_UNBIND);
868 Label label = releaseLabel(vpnInstance, host);
869 // create private route and get label
870 DeviceId deviceId = host.location().deviceId();
871 setPrivateRoute(host, vpnInstanceId, label,
872 Objective.Operation.REMOVE);
873 // download flows
874 setFlows(deviceId, host, label, rtImport,
875 Objective.Operation.REMOVE);
876 }
877 });
878 }
879
880 @Override
881 public void onVpnPortSet(VpnPort vpnPort) {
882 // delete the flows of this vpn
883 hostService.getHosts().forEach(host -> {
884 VpnPortId vpnPortId = vpnPort.id();
885 VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
886 VpnInstance vpnInstance = vpnInstanceService
887 .getInstance(vpnInstanceId);
888 if (vpnInstance == null) {
889 log.info("why vpn instance is null");
890 return;
891 }
892 List<VpnRouteTarget> rtImport
893 = new LinkedList<>(vpnInstance.getImportRouteTargets());
894/* List<VpnRouteTarget> rtExport
895 = new LinkedList<>(vpnInstance.getExportRouteTargets());*/
896
897 if (!vpnInstanceService.exists(vpnInstanceId)) {
898 log.error(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
899 return;
900 }
901
902 if (vpnPortId.vpnPortId()
903 .equals(host.annotations().value(IFACEID))) {
904 log.info(VPN_PORT_BIND);
905 Label label = applyLabel();
906 // create private route and get label
907 DeviceId deviceId = host.location().deviceId();
908 setPrivateRoute(host, vpnInstanceId, label,
909 Objective.Operation.ADD);
910 // download flows
911 setFlows(deviceId, host, label, rtImport,
912 Objective.Operation.ADD);
913 }
914 });
915 }
916
917 /**
918 * process the gluon configuration and will update the configuration into
919 * vpn port service.
920 *
921 * @param action action
922 * @param key key
923 * @param value json node
924 */
925 private void processEtcdResponse(String action, String key, JsonNode
926 value) {
927 String[] list = key.split(SLASH);
928 String target = list[list.length - 2];
929 switch (target) {
930 case VPN_INSTANCE_TARGET:
931 VpnInstanceService vpnInstanceService
932 = DefaultServiceDirectory
933 .getService(VpnInstanceService.class);
934 vpnInstanceService.processGluonConfig(action, key, value);
935 break;
936 case VPN_PORT_TARGET:
937 VpnPortService vpnPortService = DefaultServiceDirectory
938 .getService(VpnPortService.class);
939 vpnPortService.processGluonConfig(action, key, value);
940 break;
941 case VPN_AF_TARGET:
942 VpnAfConfigService vpnAfConfigService =
943 DefaultServiceDirectory.getService(VpnAfConfigService
944 .class);
945 vpnAfConfigService.processGluonConfig(action, key, value);
946 break;
947 case BASEPORT:
948 BasePortService basePortService =
949 DefaultServiceDirectory.getService(BasePortService
950 .class);
951 basePortService.processGluonConfig(action, key, value);
952 break;
953 default:
954 log.info("why target type is invalid {}", target);
955 log.info(INVALID_TARGET_RECEIVED);
956 break;
957 }
958 }
959
960 /**
961 * parse the gluon configuration received from network config system.
962 *
963 * @param jsonNode json node
964 * @param key key
965 * @param action action
966 */
967 private void parseEtcdResponse(JsonNode jsonNode,
968 String key,
969 String action) {
970 JsonNode modifyValue = null;
971 if (action.equals(SET)) {
972 modifyValue = jsonNode.get(key);
973 }
974 processEtcdResponse(action, key, modifyValue);
975 }
976
977 /**
978 * Listener for network config events.
979 */
980 private class InternalNetworkConfigListener implements
981 NetworkConfigListener {
982
983 @Override
984 public void event(NetworkConfigEvent event) {
985 String subject;
986 log.info(NETWORK_CONFIG_EVENT_IS_RECEIVED, event.type());
987 if (!event.configClass().equals(GluonConfig.class)) {
988 return;
989 }
990 log.info("Event is received from network configuration {}", event
991 .type());
992 switch (event.type()) {
993 case CONFIG_UPDATED:
994 subject = (String) event.subject();
995 GluonConfig gluonConfig = configService
996 .getConfig(subject, GluonConfig.class);
997 JsonNode jsonNode = gluonConfig.node();
998 parseEtcdResponse(jsonNode, subject, SET);
999 break;
1000 case CONFIG_REMOVED:
1001 subject = (String) event.subject();
1002 parseEtcdResponse(null, subject, DELETE);
1003 break;
1004 default:
1005 log.info(INVALID_EVENT_RECEIVED);
1006 break;
1007 }
1008 }
1009 }
1010
1011 /**
1012 * update import and export route target information in route admin service.
1013 *
1014 * @param evpnInstanceName evpn instance name
1015 * @param exportRouteTargets export route targets
1016 * @param importRouteTargets import route targets
1017 * @param action action holds update or delete
1018 */
1019 private void updateImpExpRtInRoute(EvpnInstanceName evpnInstanceName,
1020 Set<VpnRouteTarget> exportRouteTargets,
1021 Set<VpnRouteTarget> importRouteTargets,
1022 String action) {
1023
1024 for (EvpnInstanceRoute evpnInstanceRoute : evpnInstanceRoutes) {
1025 if (evpnInstanceRoute.evpnInstanceName().equals(evpnInstanceName)) {
1026 evpnInstanceRoute
1027 .setExportRtList(new LinkedList<>(exportRouteTargets));
1028 evpnInstanceRoute
1029 .setImportRtList(new LinkedList<>(importRouteTargets));
1030 if (action.equals(UPDATE)) {
1031 evpnInstanceRoutes.add(evpnInstanceRoute);
1032 } else if (action.equals(DELETE)) {
1033 evpnInstanceRoutes.remove(evpnInstanceRoute);
1034 }
1035 //Get the public route and update route targets.
1036 EvpnNextHop evpnNextHop = EvpnNextHop
1037 .evpnNextHop(evpnInstanceRoute.getNextHopl(),
1038 evpnInstanceRoute.importRouteTarget(),
1039 evpnInstanceRoute.exportRouteTarget(),
1040 evpnInstanceRoute.getLabel());
1041 Collection<EvpnRoute> evpnPublicRoutes
1042 = evpnRouteStore.getRoutesForNextHop(evpnNextHop.nextHop());
1043 for (EvpnRoute pubRoute : evpnPublicRoutes) {
1044 EvpnRoute evpnPubRoute = pubRoute;
1045 if (evpnPubRoute.label().equals(evpnInstanceRoute
1046 .getLabel())) {
1047 evpnPubRoute
1048 .setExportRtList(new LinkedList<>(exportRouteTargets));
1049 evpnPubRoute
1050 .setImportRtList(new LinkedList<>(importRouteTargets));
1051 if (action.equals(UPDATE)) {
1052 evpnRouteAdminService.update(Sets.newHashSet(evpnPubRoute));
1053 } else if (action.equals(DELETE)) {
1054 evpnRouteAdminService
1055 .withdraw(Sets.newHashSet(evpnPubRoute));
1056 }
1057 }
1058 }
1059 }
1060 }
1061 }
1062
1063 /**
1064 * update or withdraw evpn route based on vpn af configuration.
1065 *
1066 * @param vpnAfConfig vpn af configuration
1067 * @param action action holds update or delete
1068 */
1069
1070 private void processEvpnRouteUpdate(VpnAfConfig vpnAfConfig,
1071 String action) {
1072 Collection<VpnInstance> instances
1073 = vpnInstanceService.getInstances();
1074 for (VpnInstance vpnInstance : instances) {
1075 Set<VpnRouteTarget> configRouteTargets
1076 = vpnInstance.getConfigRouteTargets();
1077 for (VpnRouteTarget vpnRouteTarget : configRouteTargets) {
1078 if (vpnRouteTarget.equals(vpnAfConfig.routeTarget())) {
1079 Set<VpnRouteTarget> exportRouteTargets
1080 = vpnInstance.getExportRouteTargets();
1081 Set<VpnRouteTarget> importRouteTargets
1082 = vpnInstance.getImportRouteTargets();
1083 String routeTargetType = vpnAfConfig.routeTargetType();
1084 if (action.equals(UPDATE)) {
1085 vpnInstanceService
1086 .updateImpExpRouteTargets(routeTargetType,
1087 exportRouteTargets,
1088 importRouteTargets,
1089 vpnRouteTarget);
1090 } else if (action.equals(DELETE)) {
1091 switch (routeTargetType) {
1092 case EXPORT_EXTCOMMUNITY:
1093 exportRouteTargets.remove(vpnRouteTarget);
1094 break;
1095 case IMPORT_EXTCOMMUNITY:
1096 importRouteTargets.remove(vpnRouteTarget);
1097 break;
1098 case BOTH:
1099 exportRouteTargets.remove(vpnRouteTarget);
1100 importRouteTargets.remove(vpnRouteTarget);
1101 break;
1102 default:
1103 log.info(INVALID_ROUTE_TARGET_TYPE);
1104 break;
1105 }
1106 }
1107 updateImpExpRtInRoute(vpnInstance.vpnInstanceName(),
1108 exportRouteTargets,
1109 importRouteTargets,
1110 action);
1111 }
1112 }
1113 }
1114 }
1115
1116 private class InnerVpnAfConfigListener implements VpnAfConfigListener {
1117
1118 @Override
1119 public void event(VpnAfConfigEvent event) {
1120 VpnAfConfig vpnAfConfig = event.subject();
1121 if (VpnAfConfigEvent.Type.VPN_AF_CONFIG_DELETE == event.type()) {
1122 processEvpnRouteUpdate(vpnAfConfig, DELETE);
1123 } else if (VpnAfConfigEvent.Type.VPN_AF_CONFIG_SET
1124 == event.type() || VpnAfConfigEvent.Type
1125 .VPN_AF_CONFIG_UPDATE == event.type()) {
1126 processEvpnRouteUpdate(vpnAfConfig, UPDATE);
1127 }
1128 }
1129 }
1130}