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