blob: 97fd1224265e032fd3c8a3bd439f441cd8b39fc9 [file] [log] [blame]
jiangruif675cd42015-11-27 15:03:59 +08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
jiangruif675cd42015-11-27 15:03:59 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.vtnrsc.service.impl;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import java.util.HashSet;
22import java.util.Iterator;
23import java.util.Set;
24
25import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
30import org.apache.felix.scr.annotations.Service;
31import org.onlab.packet.IpAddress;
32import org.onlab.packet.MacAddress;
33import org.onlab.util.KryoNamespace;
34import org.onosproject.core.CoreService;
Mahesh Poojary Scc11f722015-11-29 16:09:56 +053035import org.onosproject.event.AbstractListenerManager;
jiangruif675cd42015-11-27 15:03:59 +080036import org.onosproject.net.Device;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.Host;
39import org.onosproject.net.HostId;
jiangruif675cd42015-11-27 15:03:59 +080040import org.onosproject.net.device.DeviceService;
lishuaib43dbf72016-01-06 11:11:35 +080041import org.onosproject.net.host.HostService;
jiangruif675cd42015-11-27 15:03:59 +080042import org.onosproject.store.serializers.KryoNamespaces;
43import org.onosproject.store.service.EventuallyConsistentMap;
44import org.onosproject.store.service.LogicalClockService;
45import org.onosproject.store.service.StorageService;
46import org.onosproject.vtnrsc.FixedIp;
47import org.onosproject.vtnrsc.FloatingIp;
lishuaib43dbf72016-01-06 11:11:35 +080048import org.onosproject.vtnrsc.FlowClassifier;
49import org.onosproject.vtnrsc.PortChain;
50import org.onosproject.vtnrsc.PortPair;
51import org.onosproject.vtnrsc.PortPairGroup;
52import org.onosproject.vtnrsc.PortPairId;
jiangruif675cd42015-11-27 15:03:59 +080053import org.onosproject.vtnrsc.Router;
54import org.onosproject.vtnrsc.RouterInterface;
55import org.onosproject.vtnrsc.SegmentationId;
56import org.onosproject.vtnrsc.Subnet;
57import org.onosproject.vtnrsc.SubnetId;
58import org.onosproject.vtnrsc.TenantId;
lishuai8798bbe2016-05-05 16:02:03 +080059import org.onosproject.vtnrsc.TenantRouter;
jiangruif675cd42015-11-27 15:03:59 +080060import org.onosproject.vtnrsc.VirtualPort;
61import org.onosproject.vtnrsc.VirtualPortId;
62import org.onosproject.vtnrsc.event.VtnRscEvent;
63import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
64import org.onosproject.vtnrsc.event.VtnRscListener;
65import org.onosproject.vtnrsc.floatingip.FloatingIpEvent;
66import org.onosproject.vtnrsc.floatingip.FloatingIpListener;
67import org.onosproject.vtnrsc.floatingip.FloatingIpService;
lishuaib43dbf72016-01-06 11:11:35 +080068import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent;
69import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
70import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
71import org.onosproject.vtnrsc.portchain.PortChainEvent;
72import org.onosproject.vtnrsc.portchain.PortChainListener;
73import org.onosproject.vtnrsc.portchain.PortChainService;
74import org.onosproject.vtnrsc.portpair.PortPairEvent;
75import org.onosproject.vtnrsc.portpair.PortPairListener;
76import org.onosproject.vtnrsc.portpair.PortPairService;
77import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent;
78import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
79import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
jiangruif675cd42015-11-27 15:03:59 +080080import org.onosproject.vtnrsc.router.RouterEvent;
81import org.onosproject.vtnrsc.router.RouterListener;
82import org.onosproject.vtnrsc.router.RouterService;
83import org.onosproject.vtnrsc.routerinterface.RouterInterfaceEvent;
84import org.onosproject.vtnrsc.routerinterface.RouterInterfaceListener;
85import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
86import org.onosproject.vtnrsc.service.VtnRscService;
87import org.onosproject.vtnrsc.subnet.SubnetService;
88import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
89import org.onosproject.vtnrsc.virtualport.VirtualPortService;
90import org.slf4j.Logger;
91
jiangruif675cd42015-11-27 15:03:59 +080092/**
93 * Provides implementation of the VtnRsc service.
94 */
95@Component(immediate = true)
96@Service
Mahesh Poojary Scc11f722015-11-29 16:09:56 +053097public class VtnRscManager extends AbstractListenerManager<VtnRscEvent, VtnRscListener>
98 implements VtnRscService {
jiangruif675cd42015-11-27 15:03:59 +080099 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected CoreService coreService;
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected StorageService storageService;
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected LogicalClockService clockService;
105
106 private final Logger log = getLogger(getClass());
jiangruif675cd42015-11-27 15:03:59 +0800107 private FloatingIpListener floatingIpListener = new InnerFloatingIpListener();
108 private RouterListener routerListener = new InnerRouterListener();
109 private RouterInterfaceListener routerInterfaceListener = new InnerRouterInterfaceListener();
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530110 private PortPairListener portPairListener = new InnerPortPairListener();
111 private PortPairGroupListener portPairGroupListener = new InnerPortPairGroupListener();
112 private FlowClassifierListener flowClassifierListener = new InnerFlowClassifierListener();
113 private PortChainListener portChainListener = new InnerPortChainListener();
jiangruif675cd42015-11-27 15:03:59 +0800114
lishuai8798bbe2016-05-05 16:02:03 +0800115 private EventuallyConsistentMap<TenantId, SegmentationId> l3vniTenantMap;
116 private EventuallyConsistentMap<TenantRouter, SegmentationId> l3vniTenantRouterMap;
jiangruif675cd42015-11-27 15:03:59 +0800117 private EventuallyConsistentMap<TenantId, Set<DeviceId>> classifierOvsMap;
118 private EventuallyConsistentMap<TenantId, Set<DeviceId>> sffOvsMap;
119
120 private static final String IFACEID = "ifaceid";
121 private static final String RUNNELOPTOPOIC = "tunnel-ops-ids";
jiangruif675cd42015-11-27 15:03:59 +0800122 private static final String EVENT_NOT_NULL = "event cannot be null";
123 private static final String TENANTID_NOT_NULL = "tenantId cannot be null";
124 private static final String DEVICEID_NOT_NULL = "deviceId cannot be null";
lishuaib43dbf72016-01-06 11:11:35 +0800125 private static final String VIRTUALPORTID_NOT_NULL = "virtualPortId cannot be null";
126 private static final String HOST_NOT_NULL = "host cannot be null";
lishuai8798bbe2016-05-05 16:02:03 +0800127 private static final String L3VNITENANTMAP = "l3vniTenantMap";
128 private static final String L3VNITENANTROUTERMAP = "l3vniTenantRouterMap";
jiangruif675cd42015-11-27 15:03:59 +0800129 private static final String CLASSIFIEROVSMAP = "classifierOvsMap";
130 private static final String SFFOVSMAP = "sffOvsMap";
131
132 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
133 protected RouterService routerService;
134 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
135 protected FloatingIpService floatingIpService;
136 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
137 protected RouterInterfaceService routerInterfaceService;
138 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
139 protected VirtualPortService virtualPortService;
140 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
141 protected HostService hostService;
142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
143 protected SubnetService subnetService;
144 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
145 protected TenantNetworkService tenantNetworkService;
146 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
147 protected DeviceService deviceService;
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530148 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
149 protected PortPairService portPairService;
150 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
151 protected PortPairGroupService portPairGroupService;
152 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
153 protected FlowClassifierService flowClassifierService;
154 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
155 protected PortChainService portChainService;
jiangruif675cd42015-11-27 15:03:59 +0800156
157 @Activate
158 public void activate() {
Phaneendra Manda5f326872015-12-07 19:25:09 +0530159 eventDispatcher.addSink(VtnRscEvent.class, listenerRegistry);
jiangruif675cd42015-11-27 15:03:59 +0800160 floatingIpService.addListener(floatingIpListener);
161 routerService.addListener(routerListener);
162 routerInterfaceService.addListener(routerInterfaceListener);
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530163 portPairService.addListener(portPairListener);
164 portPairGroupService.addListener(portPairGroupListener);
165 flowClassifierService.addListener(flowClassifierListener);
166 portChainService.addListener(portChainListener);
jiangruif675cd42015-11-27 15:03:59 +0800167
168 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
169 .register(KryoNamespaces.API)
lishuaieb04e7b2016-05-04 16:59:08 +0800170 .register(TenantId.class, DeviceId.class, SegmentationId.class);
lishuai8798bbe2016-05-05 16:02:03 +0800171 l3vniTenantMap = storageService
jiangruif675cd42015-11-27 15:03:59 +0800172 .<TenantId, SegmentationId>eventuallyConsistentMapBuilder()
lishuai8798bbe2016-05-05 16:02:03 +0800173 .withName(L3VNITENANTMAP).withSerializer(serializer)
174 .withTimestampProvider((k, v) -> clockService.getTimestamp())
175 .build();
176
177 l3vniTenantRouterMap = storageService
178 .<TenantRouter, SegmentationId>eventuallyConsistentMapBuilder()
179 .withName(L3VNITENANTROUTERMAP).withSerializer(serializer)
jiangruif675cd42015-11-27 15:03:59 +0800180 .withTimestampProvider((k, v) -> clockService.getTimestamp())
181 .build();
182
183 classifierOvsMap = storageService
184 .<TenantId, Set<DeviceId>>eventuallyConsistentMapBuilder()
185 .withName(CLASSIFIEROVSMAP).withSerializer(serializer)
186 .withTimestampProvider((k, v) -> clockService.getTimestamp())
187 .build();
188
189 sffOvsMap = storageService
190 .<TenantId, Set<DeviceId>>eventuallyConsistentMapBuilder()
191 .withName(SFFOVSMAP).withSerializer(serializer)
192 .withTimestampProvider((k, v) -> clockService.getTimestamp())
193 .build();
194 }
195
196 @Deactivate
197 public void deactivate() {
Phaneendra Manda5f326872015-12-07 19:25:09 +0530198 eventDispatcher.removeSink(VtnRscEvent.class);
jiangruif675cd42015-11-27 15:03:59 +0800199 floatingIpService.removeListener(floatingIpListener);
200 routerService.removeListener(routerListener);
201 routerInterfaceService.removeListener(routerInterfaceListener);
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530202 portPairService.removeListener(portPairListener);
203 portPairGroupService.removeListener(portPairGroupListener);
204 flowClassifierService.removeListener(flowClassifierListener);
205 portChainService.removeListener(portChainListener);
206
lishuai8798bbe2016-05-05 16:02:03 +0800207 l3vniTenantMap.destroy();
208 l3vniTenantRouterMap.destroy();
jiangruif675cd42015-11-27 15:03:59 +0800209 classifierOvsMap.destroy();
210 sffOvsMap.destroy();
jiangruif675cd42015-11-27 15:03:59 +0800211 log.info("Stopped");
212 }
213
214 @Override
jiangruif675cd42015-11-27 15:03:59 +0800215 public SegmentationId getL3vni(TenantId tenantId) {
216 checkNotNull(tenantId, "tenantId cannot be null");
lishuai8798bbe2016-05-05 16:02:03 +0800217 SegmentationId l3vni = l3vniTenantMap.get(tenantId);
jiangruif675cd42015-11-27 15:03:59 +0800218 if (l3vni == null) {
219 long segmentationId = coreService.getIdGenerator(RUNNELOPTOPOIC)
220 .getNewId();
221 l3vni = SegmentationId.segmentationId(String
222 .valueOf(segmentationId));
lishuai8798bbe2016-05-05 16:02:03 +0800223 l3vniTenantMap.put(tenantId, l3vni);
224 }
225 return l3vni;
226 }
227
228 @Override
229 public SegmentationId getL3vni(TenantRouter tenantRouter) {
230 checkNotNull(tenantRouter, "tenantRouter cannot be null");
231 SegmentationId l3vni = l3vniTenantRouterMap.get(tenantRouter);
232 if (l3vni == null) {
233 long segmentationId = coreService.getIdGenerator(RUNNELOPTOPOIC)
234 .getNewId();
235 l3vni = SegmentationId.segmentationId(String
236 .valueOf(segmentationId));
237 l3vniTenantRouterMap.put(tenantRouter, l3vni);
jiangruif675cd42015-11-27 15:03:59 +0800238 }
239 return l3vni;
240 }
241
jiangruif675cd42015-11-27 15:03:59 +0800242 private class InnerFloatingIpListener implements FloatingIpListener {
243
244 @Override
245 public void event(FloatingIpEvent event) {
246 checkNotNull(event, EVENT_NOT_NULL);
247 FloatingIp floatingIp = event.subject();
248 if (FloatingIpEvent.Type.FLOATINGIP_PUT == event.type()) {
249 notifyListeners(new VtnRscEvent(
250 VtnRscEvent.Type.FLOATINGIP_PUT,
251 new VtnRscEventFeedback(
252 floatingIp)));
253 }
254 if (FloatingIpEvent.Type.FLOATINGIP_DELETE == event.type()) {
255 notifyListeners(new VtnRscEvent(
256 VtnRscEvent.Type.FLOATINGIP_DELETE,
257 new VtnRscEventFeedback(
258 floatingIp)));
259 }
lishuai762df812016-01-08 11:51:15 +0800260 if (FloatingIpEvent.Type.FLOATINGIP_BIND == event.type()) {
261 notifyListeners(new VtnRscEvent(
262 VtnRscEvent.Type.FLOATINGIP_BIND,
263 new VtnRscEventFeedback(
264 floatingIp)));
265 }
266 if (FloatingIpEvent.Type.FLOATINGIP_UNBIND == event.type()) {
267 notifyListeners(new VtnRscEvent(
268 VtnRscEvent.Type.FLOATINGIP_UNBIND,
269 new VtnRscEventFeedback(
270 floatingIp)));
271 }
jiangruif675cd42015-11-27 15:03:59 +0800272 }
273 }
274
275 private class InnerRouterListener implements RouterListener {
276
277 @Override
278 public void event(RouterEvent event) {
279 checkNotNull(event, EVENT_NOT_NULL);
280 Router router = event.subject();
281 if (RouterEvent.Type.ROUTER_PUT == event.type()) {
282 notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_PUT,
283 new VtnRscEventFeedback(router)));
284 }
285 if (RouterEvent.Type.ROUTER_DELETE == event.type()) {
286 notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_DELETE,
287 new VtnRscEventFeedback(router)));
288 }
289 }
290 }
291
292 private class InnerRouterInterfaceListener
293 implements RouterInterfaceListener {
294
295 @Override
296 public void event(RouterInterfaceEvent event) {
297 checkNotNull(event, EVENT_NOT_NULL);
298 RouterInterface routerInterface = event.subject();
299 if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
300 notifyListeners(new VtnRscEvent(
301 VtnRscEvent.Type.ROUTER_INTERFACE_PUT,
302 new VtnRscEventFeedback(
303 routerInterface)));
304 }
305 if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_DELETE == event
306 .type()) {
307 notifyListeners(new VtnRscEvent(
308 VtnRscEvent.Type.ROUTER_INTERFACE_DELETE,
309 new VtnRscEventFeedback(
310 routerInterface)));
311 }
312 }
313 }
314
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530315 private class InnerPortPairListener implements PortPairListener {
316
317 @Override
318 public void event(PortPairEvent event) {
319 checkNotNull(event, EVENT_NOT_NULL);
320 PortPair portPair = event.subject();
321 if (PortPairEvent.Type.PORT_PAIR_PUT == event.type()) {
322 notifyListeners(new VtnRscEvent(VtnRscEvent.Type.PORT_PAIR_PUT,
323 new VtnRscEventFeedback(portPair)));
324 } else if (PortPairEvent.Type.PORT_PAIR_DELETE == event.type()) {
325 notifyListeners(new VtnRscEvent(
326 VtnRscEvent.Type.PORT_PAIR_DELETE,
327 new VtnRscEventFeedback(portPair)));
328 } else if (PortPairEvent.Type.PORT_PAIR_UPDATE == event.type()) {
329 notifyListeners(new VtnRscEvent(
330 VtnRscEvent.Type.PORT_PAIR_UPDATE,
331 new VtnRscEventFeedback(portPair)));
332 }
333 }
334 }
335
336 private class InnerPortPairGroupListener implements PortPairGroupListener {
337
338 @Override
339 public void event(PortPairGroupEvent event) {
340 checkNotNull(event, EVENT_NOT_NULL);
341 PortPairGroup portPairGroup = event.subject();
342 if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
343 notifyListeners(new VtnRscEvent(
344 VtnRscEvent.Type.PORT_PAIR_GROUP_PUT,
345 new VtnRscEventFeedback(portPairGroup)));
346 } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
347 notifyListeners(new VtnRscEvent(
348 VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE,
349 new VtnRscEventFeedback(portPairGroup)));
350 } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
351 notifyListeners(new VtnRscEvent(
352 VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE,
353 new VtnRscEventFeedback(portPairGroup)));
354 }
355 }
356 }
357
358 private class InnerFlowClassifierListener implements FlowClassifierListener {
359
360 @Override
361 public void event(FlowClassifierEvent event) {
362 checkNotNull(event, EVENT_NOT_NULL);
363 FlowClassifier flowClassifier = event.subject();
364 if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
365 notifyListeners(new VtnRscEvent(
366 VtnRscEvent.Type.FLOW_CLASSIFIER_PUT,
367 new VtnRscEventFeedback(flowClassifier)));
368 } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
369 notifyListeners(new VtnRscEvent(
370 VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE,
371 new VtnRscEventFeedback(flowClassifier)));
372 } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
373 notifyListeners(new VtnRscEvent(
374 VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE,
375 new VtnRscEventFeedback(flowClassifier)));
376 }
377 }
378 }
379
380 private class InnerPortChainListener implements PortChainListener {
381
382 @Override
383 public void event(PortChainEvent event) {
384 checkNotNull(event, EVENT_NOT_NULL);
385 PortChain portChain = event.subject();
386 if (PortChainEvent.Type.PORT_CHAIN_PUT == event.type()) {
387 notifyListeners(new VtnRscEvent(
388 VtnRscEvent.Type.PORT_CHAIN_PUT,
389 new VtnRscEventFeedback(portChain)));
390 } else if (PortChainEvent.Type.PORT_CHAIN_DELETE == event.type()) {
391 notifyListeners(new VtnRscEvent(
392 VtnRscEvent.Type.PORT_CHAIN_DELETE,
393 new VtnRscEventFeedback(portChain)));
394 } else if (PortChainEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
395 notifyListeners(new VtnRscEvent(
396 VtnRscEvent.Type.PORT_CHAIN_UPDATE,
397 new VtnRscEventFeedback(portChain)));
398 }
399 }
400 }
401
jiangruif675cd42015-11-27 15:03:59 +0800402 @Override
403 public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
404 checkNotNull(tenantId, TENANTID_NOT_NULL);
405 Set<DeviceId> deviceIdSet = classifierOvsMap.get(tenantId);
406 Set<Device> deviceSet = new HashSet<>();
407 if (deviceIdSet != null) {
408 for (DeviceId deviceId : deviceIdSet) {
409 deviceSet.add(deviceService.getDevice(deviceId));
410 }
411 }
412 return deviceSet.iterator();
413 }
414
415 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700416 public Iterator<Device> getSffOfTenant(TenantId tenantId) {
jiangruif675cd42015-11-27 15:03:59 +0800417 checkNotNull(tenantId, TENANTID_NOT_NULL);
418 Set<DeviceId> deviceIdSet = sffOvsMap.get(tenantId);
419 Set<Device> deviceSet = new HashSet<>();
420 if (deviceIdSet != null) {
421 for (DeviceId deviceId : deviceIdSet) {
422 deviceSet.add(deviceService.getDevice(deviceId));
423 }
424 }
425 return deviceSet.iterator();
426 }
427
428 @Override
429 public MacAddress getGatewayMac(HostId hostId) {
430 checkNotNull(hostId, "hostId cannot be null");
431 Host host = hostService.getHost(hostId);
432 String ifaceId = host.annotations().value(IFACEID);
433 VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
434 VirtualPort hPort = virtualPortService.getPort(hPortId);
435 SubnetId subnetId = hPort.fixedIps().iterator().next().subnetId();
436 Subnet subnet = subnetService.getSubnet(subnetId);
437 IpAddress gatewayIp = subnet.gatewayIp();
438 Iterable<VirtualPort> virtualPorts = virtualPortService.getPorts();
439 MacAddress macAddress = null;
440 for (VirtualPort port : virtualPorts) {
441 Set<FixedIp> fixedIpSet = port.fixedIps();
442 for (FixedIp fixedIp : fixedIpSet) {
443 if (fixedIp.ip().equals(gatewayIp)) {
444 macAddress = port.macAddress();
445 }
446 }
447 }
448 return macAddress;
449 }
450
451 @Override
452 public boolean isServiceFunction(VirtualPortId portId) {
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530453 return portPairService.exists(PortPairId.of(portId.portId()));
jiangruif675cd42015-11-27 15:03:59 +0800454 }
455
456 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700457 public DeviceId getSfToSffMaping(VirtualPortId portId) {
jiangruif675cd42015-11-27 15:03:59 +0800458 checkNotNull(portId, "portId cannot be null");
459 VirtualPort vmPort = virtualPortService.getPort(portId);
460 Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
461 for (Host host : hostSet) {
Satish K01a60f22015-11-28 15:21:42 +0530462 if (host.annotations().value(IFACEID).equals(vmPort.portId().portId())) {
jiangruif675cd42015-11-27 15:03:59 +0800463 return host.location().deviceId();
464 }
465 }
466 return null;
467 }
468
lishuaib43dbf72016-01-06 11:11:35 +0800469 @Override
470 public void addDeviceIdOfOvsMap(VirtualPortId virtualPortId,
471 TenantId tenantId, DeviceId deviceId) {
472 checkNotNull(virtualPortId, VIRTUALPORTID_NOT_NULL);
473 checkNotNull(tenantId, TENANTID_NOT_NULL);
474 checkNotNull(deviceId, DEVICEID_NOT_NULL);
475 if (isServiceFunction(virtualPortId)) {
476 addDeviceIdToSpecificMap(tenantId, deviceId, sffOvsMap);
477 } else {
478 addDeviceIdToSpecificMap(tenantId, deviceId, classifierOvsMap);
479 }
480 }
481
482 @Override
483 public void removeDeviceIdOfOvsMap(Host host, TenantId tenantId, DeviceId deviceId) {
484 checkNotNull(host, HOST_NOT_NULL);
485 checkNotNull(tenantId, TENANTID_NOT_NULL);
486 checkNotNull(deviceId, DEVICEID_NOT_NULL);
487 if (isLastSFHostOfTenant(host, deviceId, tenantId)) {
488 removeDeviceIdToSpecificMap(tenantId, deviceId, sffOvsMap);
489 }
490 if (isLastClassifierHostOfTenant(host, deviceId, tenantId)) {
491 removeDeviceIdToSpecificMap(tenantId, deviceId, classifierOvsMap);
492 }
493 }
494
jiangruif675cd42015-11-27 15:03:59 +0800495 /**
496 * Checks whether the last Service Function host of a specific tenant in
497 * this device.
498 *
499 * @param host the host on device
500 * @param deviceId the device identifier
501 * @param tenantId the tenant identifier
502 * @return true or false
503 */
504 private boolean isLastSFHostOfTenant(Host host, DeviceId deviceId,
505 TenantId tenantId) {
jiangruif675cd42015-11-27 15:03:59 +0800506 Set<Host> hostSet = hostService.getConnectedHosts(deviceId);
lishuai1fbd41b2015-12-10 16:44:57 +0800507 if (hostSet != null) {
508 for (Host h : hostSet) {
509 String ifaceId = h.annotations().value(IFACEID);
510 if (ifaceId != null) {
511 VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
512 if (virtualPortService.getPort(hPortId).tenantId().tenantId()
513 .equals(tenantId.tenantId())
514 && isServiceFunction(hPortId)) {
lishuaib43dbf72016-01-06 11:11:35 +0800515 if (!h.equals(host)) {
516 return false;
517 }
lishuai1fbd41b2015-12-10 16:44:57 +0800518 }
jiangruif675cd42015-11-27 15:03:59 +0800519 }
520 }
521 }
lishuaib43dbf72016-01-06 11:11:35 +0800522 return true;
jiangruif675cd42015-11-27 15:03:59 +0800523 }
524
525 /**
526 * Checks whether the last Classifier host of a specific tenant in this
527 * device.
528 *
529 * @param host the host on device
530 * @param deviceId the device identifier
531 * @param tenantId the tenant identifier
532 * @return true or false
533 */
534 private boolean isLastClassifierHostOfTenant(Host host, DeviceId deviceId,
535 TenantId tenantId) {
jiangruif675cd42015-11-27 15:03:59 +0800536 Set<Host> hostSet = hostService.getConnectedHosts(deviceId);
lishuai1fbd41b2015-12-10 16:44:57 +0800537 if (hostSet != null) {
538 for (Host h : hostSet) {
539 String ifaceId = h.annotations().value(IFACEID);
540 if (ifaceId != null) {
541 VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
542 if (virtualPortService.getPort(hPortId).tenantId().tenantId()
543 .equals(tenantId.tenantId())
544 && !isServiceFunction(hPortId)) {
lishuaib43dbf72016-01-06 11:11:35 +0800545 if (!h.equals(host)) {
546 return false;
547 }
lishuai1fbd41b2015-12-10 16:44:57 +0800548 }
jiangruif675cd42015-11-27 15:03:59 +0800549 }
550 }
551 }
lishuaib43dbf72016-01-06 11:11:35 +0800552 return true;
jiangruif675cd42015-11-27 15:03:59 +0800553 }
554
555 /**
556 * Adds specify Device identifier to OvsMap.
557 *
558 * @param tenantId the tenant identifier
559 * @param deviceId the device identifier
560 * @param ovsMap the instance of map to store device identifier
561 */
lishuaib43dbf72016-01-06 11:11:35 +0800562 private void addDeviceIdToSpecificMap(TenantId tenantId,
jiangruif675cd42015-11-27 15:03:59 +0800563 DeviceId deviceId,
564 EventuallyConsistentMap<TenantId, Set<DeviceId>> ovsMap) {
jiangruif675cd42015-11-27 15:03:59 +0800565 if (ovsMap.containsKey(tenantId)) {
566 Set<DeviceId> deviceIdSet = ovsMap.get(tenantId);
567 deviceIdSet.add(deviceId);
568 ovsMap.put(tenantId, deviceIdSet);
569 } else {
570 Set<DeviceId> deviceIdSet = new HashSet<>();
571 deviceIdSet.add(deviceId);
572 ovsMap.put(tenantId, deviceIdSet);
573 }
574 }
575
576 /**
577 * Removes specify Device identifier from OvsMap.
578 *
579 * @param tenantId the tenant identifier
580 * @param deviceId the device identifier
581 * @param ovsMap the instance of map to store device identifier
582 */
lishuaib43dbf72016-01-06 11:11:35 +0800583 private void removeDeviceIdToSpecificMap(TenantId tenantId,
jiangruif675cd42015-11-27 15:03:59 +0800584 DeviceId deviceId,
585 EventuallyConsistentMap<TenantId, Set<DeviceId>> ovsMap) {
jiangruif675cd42015-11-27 15:03:59 +0800586 Set<DeviceId> deviceIdSet = ovsMap.get(tenantId);
lishuaib43dbf72016-01-06 11:11:35 +0800587 if (deviceIdSet != null && deviceIdSet.size() > 1) {
jiangruif675cd42015-11-27 15:03:59 +0800588 deviceIdSet.remove(deviceId);
589 ovsMap.put(tenantId, deviceIdSet);
590 } else {
591 ovsMap.remove(tenantId);
592 }
593 }
594
595 /**
596 * Notifies specify event to all listeners.
597 *
598 * @param event VtnRsc event
599 */
600 private void notifyListeners(VtnRscEvent event) {
601 checkNotNull(event, EVENT_NOT_NULL);
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530602 post(event);
jiangruif675cd42015-11-27 15:03:59 +0800603 }
604}