blob: 6429314e1b3c6fe635547d4ae858f3abe0ada800 [file] [log] [blame]
lishuai6c56f5e2015-11-17 16:38:19 +08001/*
2 * Copyright 2015 Open Networking Laboratory
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 */
16package org.onosproject.vtn.manager.impl;
17
jiangruic69a7fd2015-11-19 15:40:01 +080018import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
lishuai6c56f5e2015-11-17 16:38:19 +080019import static org.slf4j.LoggerFactory.getLogger;
20
lishuai858efd32015-12-04 14:30:36 +080021import java.util.ArrayList;
lishuai6c56f5e2015-11-17 16:38:19 +080022import java.util.Collection;
23import java.util.HashMap;
24import java.util.HashSet;
25import java.util.Iterator;
jiangruic69a7fd2015-11-19 15:40:01 +080026import java.util.List;
lishuai6c56f5e2015-11-17 16:38:19 +080027import java.util.Map;
28import java.util.Set;
lishuai858efd32015-12-04 14:30:36 +080029import java.util.stream.Collectors;
lishuai6c56f5e2015-11-17 16:38:19 +080030
31import org.apache.felix.scr.annotations.Activate;
32import org.apache.felix.scr.annotations.Component;
33import org.apache.felix.scr.annotations.Deactivate;
34import org.apache.felix.scr.annotations.Reference;
35import org.apache.felix.scr.annotations.ReferenceCardinality;
36import org.apache.felix.scr.annotations.Service;
jiangruic69a7fd2015-11-19 15:40:01 +080037import org.onlab.packet.Ip4Address;
lishuai6c56f5e2015-11-17 16:38:19 +080038import org.onlab.packet.IpAddress;
39import org.onlab.packet.MacAddress;
40import org.onlab.util.KryoNamespace;
41import org.onosproject.core.ApplicationId;
42import org.onosproject.core.CoreService;
43import org.onosproject.mastership.MastershipService;
lishuai858efd32015-12-04 14:30:36 +080044import org.onosproject.net.AnnotationKeys;
lishuai6c56f5e2015-11-17 16:38:19 +080045import org.onosproject.net.Device;
46import org.onosproject.net.DeviceId;
47import org.onosproject.net.Host;
lishuai858efd32015-12-04 14:30:36 +080048import org.onosproject.net.HostId;
lishuai6c56f5e2015-11-17 16:38:19 +080049import org.onosproject.net.Port;
50import org.onosproject.net.PortNumber;
51import org.onosproject.net.behaviour.BridgeConfig;
52import org.onosproject.net.behaviour.BridgeDescription;
jiangruic69a7fd2015-11-19 15:40:01 +080053import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
lishuai6c56f5e2015-11-17 16:38:19 +080054import org.onosproject.net.config.NetworkConfigService;
55import org.onosproject.net.config.basics.BasicDeviceConfig;
56import org.onosproject.net.device.DeviceEvent;
57import org.onosproject.net.device.DeviceListener;
58import org.onosproject.net.device.DeviceService;
59import org.onosproject.net.driver.DriverHandler;
60import org.onosproject.net.driver.DriverService;
jiangruic69a7fd2015-11-19 15:40:01 +080061import org.onosproject.net.flow.DefaultTrafficTreatment;
62import org.onosproject.net.flow.TrafficTreatment.Builder;
63import org.onosproject.net.flow.instructions.ExtensionTreatment;
lishuai6c56f5e2015-11-17 16:38:19 +080064import org.onosproject.net.flowobjective.Objective;
jiangruic69a7fd2015-11-19 15:40:01 +080065import org.onosproject.net.group.DefaultGroupBucket;
66import org.onosproject.net.group.DefaultGroupDescription;
67import org.onosproject.net.group.DefaultGroupKey;
68import org.onosproject.net.group.GroupBucket;
69import org.onosproject.net.group.GroupBuckets;
70import org.onosproject.net.group.GroupDescription;
71import org.onosproject.net.group.GroupKey;
72import org.onosproject.net.group.GroupService;
lishuai6c56f5e2015-11-17 16:38:19 +080073import org.onosproject.net.host.HostEvent;
74import org.onosproject.net.host.HostListener;
75import org.onosproject.net.host.HostService;
76import org.onosproject.store.serializers.KryoNamespaces;
lishuai6c56f5e2015-11-17 16:38:19 +080077import org.onosproject.store.service.EventuallyConsistentMap;
78import org.onosproject.store.service.LogicalClockService;
lishuai6c56f5e2015-11-17 16:38:19 +080079import org.onosproject.store.service.StorageService;
80import org.onosproject.vtn.manager.VTNService;
lishuai858efd32015-12-04 14:30:36 +080081import org.onosproject.vtn.table.ArpService;
lishuai6c56f5e2015-11-17 16:38:19 +080082import org.onosproject.vtn.table.ClassifierService;
lishuai858efd32015-12-04 14:30:36 +080083import org.onosproject.vtn.table.DnatService;
lishuai6c56f5e2015-11-17 16:38:19 +080084import org.onosproject.vtn.table.L2ForwardService;
lishuai858efd32015-12-04 14:30:36 +080085import org.onosproject.vtn.table.L3ForwardService;
86import org.onosproject.vtn.table.SnatService;
lishuai6c56f5e2015-11-17 16:38:19 +080087import org.onosproject.vtn.table.impl.ClassifierServiceImpl;
88import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
89import org.onosproject.vtn.util.DataPathIdGenerator;
90import org.onosproject.vtn.util.VtnConfig;
91import org.onosproject.vtn.util.VtnData;
lishuai7dc63d92015-11-27 17:15:25 +080092import org.onosproject.vtnrsc.AllowedAddressPair;
93import org.onosproject.vtnrsc.BindingHostId;
94import org.onosproject.vtnrsc.DefaultVirtualPort;
95import org.onosproject.vtnrsc.FixedIp;
lishuai858efd32015-12-04 14:30:36 +080096import org.onosproject.vtnrsc.FloatingIp;
97import org.onosproject.vtnrsc.Router;
98import org.onosproject.vtnrsc.RouterGateway;
99import org.onosproject.vtnrsc.RouterId;
100import org.onosproject.vtnrsc.RouterInterface;
lishuai7dc63d92015-11-27 17:15:25 +0800101import org.onosproject.vtnrsc.SecurityGroup;
lishuai6c56f5e2015-11-17 16:38:19 +0800102import org.onosproject.vtnrsc.SegmentationId;
103import org.onosproject.vtnrsc.SubnetId;
104import org.onosproject.vtnrsc.TenantId;
105import org.onosproject.vtnrsc.TenantNetwork;
106import org.onosproject.vtnrsc.TenantNetworkId;
107import org.onosproject.vtnrsc.VirtualPort;
108import org.onosproject.vtnrsc.VirtualPortId;
lishuai858efd32015-12-04 14:30:36 +0800109import org.onosproject.vtnrsc.event.VtnRscEvent;
110import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
111import org.onosproject.vtnrsc.event.VtnRscListener;
112import org.onosproject.vtnrsc.floatingip.FloatingIpService;
113import org.onosproject.vtnrsc.router.RouterService;
114import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
115import org.onosproject.vtnrsc.service.VtnRscService;
116import org.onosproject.vtnrsc.subnet.SubnetService;
lishuai6c56f5e2015-11-17 16:38:19 +0800117import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
118import org.onosproject.vtnrsc.virtualport.VirtualPortService;
119import org.slf4j.Logger;
120
jiangruic69a7fd2015-11-19 15:40:01 +0800121import com.google.common.collect.Lists;
lishuai6c56f5e2015-11-17 16:38:19 +0800122import com.google.common.collect.Sets;
123
124/**
125 * Provides implementation of VTNService.
126 */
127@Component(immediate = true)
128@Service
129public class VTNManager implements VTNService {
130 private final Logger log = getLogger(getClass());
131 private static final String APP_ID = "org.onosproject.app.vtn";
132
133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
134 protected NetworkConfigService configService;
135
136 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
137 protected DeviceService deviceService;
138
139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
140 protected HostService hostService;
141
142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
143 protected CoreService coreService;
144
145 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
146 protected StorageService storageService;
147
148 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
149 protected TenantNetworkService tenantNetworkService;
150
151 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
152 protected VirtualPortService virtualPortService;
153
154 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
155 protected DriverService driverService;
156
157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
158 protected LogicalClockService clockService;
159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
161 protected MastershipService mastershipService;
162
jiangruic69a7fd2015-11-19 15:40:01 +0800163 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
164 protected GroupService groupService;
165
lishuai858efd32015-12-04 14:30:36 +0800166 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
167 protected SubnetService subnetService;
168
169 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
170 protected VtnRscService vtnRscService;
171
172 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
173 protected FloatingIpService floatingIpService;
174
175 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
176 protected RouterService routerService;
177
178 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
179 protected RouterInterfaceService routerInterfaceService;
180
lishuai6c56f5e2015-11-17 16:38:19 +0800181 private ApplicationId appId;
182 private ClassifierService classifierService;
183 private L2ForwardService l2ForwardService;
lishuai858efd32015-12-04 14:30:36 +0800184 private ArpService arpService;
185 private L3ForwardService l3ForwardService;
186 private SnatService snatService;
187 private DnatService dnatService;
lishuai6c56f5e2015-11-17 16:38:19 +0800188
189 private final HostListener hostListener = new InnerHostListener();
190 private final DeviceListener deviceListener = new InnerDeviceListener();
lishuai858efd32015-12-04 14:30:36 +0800191 private final VtnRscListener l3EventListener = new VtnL3EventListener();
lishuai6c56f5e2015-11-17 16:38:19 +0800192
193 private static final String IFACEID = "ifaceid";
194 private static final String CONTROLLER_IP_KEY = "ipaddress";
195 public static final String DRIVER_NAME = "onosfw";
196 private static final String EX_PORT_NAME = "eth0";
lishuai7dc63d92015-11-27 17:15:25 +0800197 private static final String VIRTUALPORT = "vtn-virtual-port";
lishuai6c56f5e2015-11-17 16:38:19 +0800198 private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
199 private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
lishuai858efd32015-12-04 14:30:36 +0800200 private static final String ROUTERINF_FLAG_OF_TENANT = "routerInfFlagOfTenant";
201 private static final String HOSTS_OF_SUBNET = "hostsOfSubnet";
202 private static final String EX_PORT_OF_DEVICE = "exPortOfDevice";
jiangruic69a7fd2015-11-19 15:40:01 +0800203 private static final String DEFAULT_IP = "0.0.0.0";
lishuai858efd32015-12-04 14:30:36 +0800204 private static final String PORT_MAC = "portMac";
205 private static final int SUBNET_NUM = 2;
lishuai6c56f5e2015-11-17 16:38:19 +0800206
lishuai7dc63d92015-11-27 17:15:25 +0800207 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
lishuai6c56f5e2015-11-17 16:38:19 +0800208 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
jiangruic69a7fd2015-11-19 15:40:01 +0800209 private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
lishuai858efd32015-12-04 14:30:36 +0800210 private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet;
211 private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant;
212 private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice;
lishuai6c56f5e2015-11-17 16:38:19 +0800213
214 @Activate
215 public void activate() {
216 appId = coreService.registerApplication(APP_ID);
217 classifierService = new ClassifierServiceImpl(appId);
218 l2ForwardService = new L2ForwardServiceImpl(appId);
219
220 deviceService.addListener(deviceListener);
221 hostService.addListener(hostListener);
222
223 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
224 .register(KryoNamespaces.API)
225 .register(NetworkOfLocalHostPorts.class)
226 .register(TenantNetworkId.class)
227 .register(Host.class)
228 .register(TenantNetwork.class)
229 .register(TenantId.class)
lishuai7dc63d92015-11-27 17:15:25 +0800230 .register(SubnetId.class)
231 .register(VirtualPortId.class)
232 .register(VirtualPort.State.class)
233 .register(AllowedAddressPair.class)
234 .register(FixedIp.class)
235 .register(BindingHostId.class)
236 .register(SecurityGroup.class)
237 .register(IpAddress.class)
238 .register(DefaultVirtualPort.class);
239
240 vPortStore = storageService
241 .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder()
242 .withName(VIRTUALPORT).withSerializer(serializer)
243 .withTimestampProvider((k, v) -> clockService.getTimestamp())
244 .build();
lishuai6c56f5e2015-11-17 16:38:19 +0800245
246 switchesOfController = storageService
247 .<IpAddress, Boolean>eventuallyConsistentMapBuilder()
248 .withName(SWITCHES_OF_CONTROLLER).withSerializer(serializer)
249 .withTimestampProvider((k, v) -> clockService.getTimestamp())
250 .build();
251
252 switchOfLocalHostPorts = storageService
jiangruic69a7fd2015-11-19 15:40:01 +0800253 .<DeviceId, NetworkOfLocalHostPorts>eventuallyConsistentMapBuilder()
254 .withName(SWITCH_OF_LOCAL_HOST_PORTS).withSerializer(serializer)
255 .withTimestampProvider((k, v) -> clockService.getTimestamp())
lishuai6c56f5e2015-11-17 16:38:19 +0800256 .build();
257
lishuai858efd32015-12-04 14:30:36 +0800258 hostsOfSubnet = storageService
259 .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder()
260 .withName(HOSTS_OF_SUBNET).withSerializer(serializer)
261 .withTimestampProvider((k, v) -> clockService.getTimestamp())
262 .build();
263
264 routerInfFlagOfTenant = storageService
265 .<TenantId, Boolean>eventuallyConsistentMapBuilder()
266 .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer)
267 .withTimestampProvider((k, v) -> clockService.getTimestamp())
268 .build();
269
270 exPortOfDevice = storageService
271 .<DeviceId, Port>eventuallyConsistentMapBuilder()
272 .withName(EX_PORT_OF_DEVICE).withSerializer(serializer)
273 .withTimestampProvider((k, v) -> clockService.getTimestamp())
274 .build();
275
lishuai6c56f5e2015-11-17 16:38:19 +0800276 log.info("Started");
277 }
278
279 @Deactivate
280 public void deactivate() {
281 deviceService.removeListener(deviceListener);
282 hostService.removeListener(hostListener);
lishuai858efd32015-12-04 14:30:36 +0800283 vtnRscService.removeListener(l3EventListener);
lishuai6c56f5e2015-11-17 16:38:19 +0800284 log.info("Stopped");
285 }
286
287 @Override
288 public void onControllerDetected(Device controllerDevice) {
289 if (controllerDevice == null) {
290 log.error("The controller device is null");
291 return;
292 }
293 String localIpAddress = controllerDevice.annotations()
294 .value(CONTROLLER_IP_KEY);
295 IpAddress localIp = IpAddress.valueOf(localIpAddress);
296 DeviceId controllerDeviceId = controllerDevice.id();
297 DriverHandler handler = driverService.createHandler(controllerDeviceId);
298 if (mastershipService.isLocalMaster(controllerDeviceId)) {
299 // Get DataPathIdGenerator
300 String ipaddress = controllerDevice.annotations().value("ipaddress");
301 DataPathIdGenerator dpidGenerator = DataPathIdGenerator.builder()
302 .addIpAddress(ipaddress).build();
303 DeviceId deviceId = dpidGenerator.getDeviceId();
304 String dpid = dpidGenerator.getDpId();
305 // Inject pipeline driver name
306 BasicDeviceConfig config = configService.addConfig(deviceId,
307 BasicDeviceConfig.class);
308 config.driver(DRIVER_NAME);
309 configService.applyConfig(deviceId, BasicDeviceConfig.class, config.node());
310 // Add Bridge
311 VtnConfig.applyBridgeConfig(handler, dpid, EX_PORT_NAME);
312 log.info("A new ovs is created in node {}", localIp.toString());
313 switchesOfController.put(localIp, true);
314 }
315 // Create tunnel in br-int on all controllers
316 programTunnelConfig(controllerDeviceId, localIp, handler);
317 }
318
319 @Override
320 public void onControllerVanished(Device controllerDevice) {
321 if (controllerDevice == null) {
322 log.error("The device is null");
323 return;
324 }
325 String dstIp = controllerDevice.annotations().value(CONTROLLER_IP_KEY);
326 IpAddress dstIpAddress = IpAddress.valueOf(dstIp);
327 DeviceId controllerDeviceId = controllerDevice.id();
328 if (mastershipService.isLocalMaster(controllerDeviceId)) {
329 switchesOfController.remove(dstIpAddress);
330 }
331 // remove tunnel in br-int on other controllers
332 programTunnelConfig(controllerDeviceId, dstIpAddress, null);
333 }
334
335 @Override
336 public void onOvsDetected(Device device) {
337 // Create tunnel out flow rules
338 applyTunnelOut(device, Objective.Operation.ADD);
339 }
340
341 @Override
342 public void onOvsVanished(Device device) {
343 // Remove Tunnel out flow rules
344 applyTunnelOut(device, Objective.Operation.REMOVE);
345 }
346
347 @Override
348 public void onHostDetected(Host host) {
lishuai858efd32015-12-04 14:30:36 +0800349 DeviceId deviceId = host.location().deviceId();
350 if (!mastershipService.isLocalMaster(deviceId)) {
351 return;
352 }
353 String ifaceId = host.annotations().value(IFACEID);
354 if (ifaceId == null) {
355 log.error("The ifaceId of Host is null");
356 return;
357 }
lishuai6c56f5e2015-11-17 16:38:19 +0800358 // apply L2 openflow rules
359 applyHostMonitoredL2Rules(host, Objective.Operation.ADD);
lishuai858efd32015-12-04 14:30:36 +0800360 // apply L3 openflow rules
361 applyHostMonitoredL3Rules(host, Objective.Operation.ADD);
lishuai6c56f5e2015-11-17 16:38:19 +0800362 }
363
364 @Override
365 public void onHostVanished(Host host) {
lishuai858efd32015-12-04 14:30:36 +0800366 DeviceId deviceId = host.location().deviceId();
367 if (!mastershipService.isLocalMaster(deviceId)) {
368 return;
369 }
370 String ifaceId = host.annotations().value(IFACEID);
371 if (ifaceId == null) {
372 log.error("The ifaceId of Host is null");
373 return;
374 }
lishuai6c56f5e2015-11-17 16:38:19 +0800375 // apply L2 openflow rules
376 applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE);
lishuai858efd32015-12-04 14:30:36 +0800377 // apply L3 openflow rules
378 applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE);
lishuai6c56f5e2015-11-17 16:38:19 +0800379 }
380
381 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
382 DriverHandler localHandler) {
jiangruic69a7fd2015-11-19 15:40:01 +0800383 if (mastershipService.isLocalMaster(localDeviceId)) {
384 VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP));
385 log.info("Add tunnel on {}", localIp);
386 }
lishuai6c56f5e2015-11-17 16:38:19 +0800387 }
388
389 private void applyTunnelOut(Device device, Objective.Operation type) {
390 if (device == null) {
391 log.error("The device is null");
392 return;
393 }
394 if (!mastershipService.isLocalMaster(device.id())) {
395 return;
396 }
397 String controllerIp = VtnData.getControllerIpOfSwitch(device);
398 if (controllerIp == null) {
399 log.error("Can't find controller of device: {}",
400 device.id().toString());
401 return;
402 }
403 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
404 if (!switchesOfController.containsKey(ipAddress)) {
405 log.error("Can't find controller of device: {}",
406 device.id().toString());
407 return;
408 }
409 if (type == Objective.Operation.ADD) {
410 switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts());
411 } else if (type == Objective.Operation.REMOVE) {
412 switchOfLocalHostPorts.remove(device.id());
413 }
414 Iterable<Device> devices = deviceService.getAvailableDevices();
415 DeviceId localControllerId = VtnData.getControllerId(device, devices);
416 DriverHandler handler = driverService.createHandler(localControllerId);
417 Set<PortNumber> ports = VtnConfig.getPortNumbers(handler);
418 Iterable<Host> allHosts = hostService.getHosts();
jiangruic69a7fd2015-11-19 15:40:01 +0800419 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800420 if (allHosts != null) {
421 Sets.newHashSet(allHosts).stream().forEach(host -> {
422 MacAddress hostMac = host.mac();
423 String ifaceId = host.annotations().value(IFACEID);
424 if (ifaceId == null) {
425 log.error("The ifaceId of Host is null");
426 return;
427 }
428 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
429 VirtualPort virtualPort = virtualPortService
430 .getPort(virtualPortId);
431 TenantNetwork network = tenantNetworkService
432 .getNetwork(virtualPort.networkId());
433 SegmentationId segmentationId = network.segmentationId();
434 DeviceId remoteDeviceId = host.location().deviceId();
435 Device remoteDevice = deviceService.getDevice(remoteDeviceId);
436 String remoteControllerIp = VtnData
437 .getControllerIpOfSwitch(remoteDevice);
438 if (remoteControllerIp == null) {
439 log.error("Can't find remote controller of device: {}",
440 remoteDeviceId.toString());
441 return;
442 }
443 IpAddress remoteIpAddress = IpAddress
444 .valueOf(remoteControllerIp);
lishuai6c56f5e2015-11-17 16:38:19 +0800445 ports.stream()
446 .filter(p -> p.name().equalsIgnoreCase(tunnelName))
447 .forEach(p -> {
448 l2ForwardService
449 .programTunnelOut(device.id(), segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800450 hostMac, type, remoteIpAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800451 });
452 });
453 }
454 }
455
456 private void applyHostMonitoredL2Rules(Host host, Objective.Operation type) {
457 DeviceId deviceId = host.location().deviceId();
458 if (!mastershipService.isLocalMaster(deviceId)) {
459 return;
460 }
461 String ifaceId = host.annotations().value(IFACEID);
462 if (ifaceId == null) {
463 log.error("The ifaceId of Host is null");
464 return;
465 }
466 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
467 VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
468 if (virtualPort == null) {
lishuai858efd32015-12-04 14:30:36 +0800469 virtualPort = VtnData.getPort(vPortStore, virtualPortId);
lishuai6c56f5e2015-11-17 16:38:19 +0800470 }
471
472 Iterable<Device> devices = deviceService.getAvailableDevices();
473 PortNumber inPort = host.location().port();
474 MacAddress mac = host.mac();
475 Device device = deviceService.getDevice(deviceId);
476 String controllerIp = VtnData.getControllerIpOfSwitch(device);
477 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
478 TenantNetwork network = tenantNetworkService.getNetwork(virtualPort.networkId());
479 if (network == null) {
480 log.error("Can't find network of the host");
481 return;
482 }
483 SegmentationId segmentationId = network.segmentationId();
484 // Get all the tunnel PortNumber in the current node
485 Iterable<Port> ports = deviceService.getPorts(deviceId);
486 Collection<PortNumber> localTunnelPorts = VtnData.getLocalTunnelPorts(ports);
487 // Get all the local vm's PortNumber in the current node
488 Map<TenantNetworkId, Set<PortNumber>> localHostPorts = switchOfLocalHostPorts
jiangruic69a7fd2015-11-19 15:40:01 +0800489 .get(deviceId).getNetworkOfLocalHostPorts();
lishuai6c56f5e2015-11-17 16:38:19 +0800490 Set<PortNumber> networkOflocalHostPorts = localHostPorts.get(network.id());
jiangruic69a7fd2015-11-19 15:40:01 +0800491 for (PortNumber p : localTunnelPorts) {
492 programGroupTable(deviceId, appId, p, devices, type);
493 }
lishuai6c56f5e2015-11-17 16:38:19 +0800494
495 if (type == Objective.Operation.ADD) {
lishuai7dc63d92015-11-27 17:15:25 +0800496 vPortStore.put(virtualPortId, virtualPort);
lishuai6c56f5e2015-11-17 16:38:19 +0800497 if (networkOflocalHostPorts == null) {
498 networkOflocalHostPorts = new HashSet<PortNumber>();
499 localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts);
500 }
501 networkOflocalHostPorts.add(inPort);
jiangruic69a7fd2015-11-19 15:40:01 +0800502 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
503 inPort, networkOflocalHostPorts,
504 localTunnelPorts,
505 type);
lishuai6c56f5e2015-11-17 16:38:19 +0800506 classifierService.programTunnelIn(deviceId, segmentationId,
507 localTunnelPorts,
508 type);
509 } else if (type == Objective.Operation.REMOVE) {
lishuai7dc63d92015-11-27 17:15:25 +0800510 vPortStore.remove(virtualPortId);
jiangruic69a7fd2015-11-19 15:40:01 +0800511 if (networkOflocalHostPorts != null) {
512 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
513 inPort, networkOflocalHostPorts,
514 localTunnelPorts,
515 type);
516 networkOflocalHostPorts.remove(inPort);
517 if (networkOflocalHostPorts.isEmpty()) {
518 classifierService.programTunnelIn(deviceId, segmentationId,
519 localTunnelPorts,
520 type);
521 switchOfLocalHostPorts.get(deviceId).getNetworkOfLocalHostPorts()
522 .remove(virtualPort.networkId());
523 }
lishuai6c56f5e2015-11-17 16:38:19 +0800524 }
525 }
526
jiangruic69a7fd2015-11-19 15:40:01 +0800527 l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac,
528 type);
529
lishuai6c56f5e2015-11-17 16:38:19 +0800530 l2ForwardService.programTunnelBcastRules(deviceId, segmentationId,
531 networkOflocalHostPorts,
532 localTunnelPorts,
533 type);
534
535 programTunnelOuts(devices, ipAddress, segmentationId, mac,
536 type);
537
538 classifierService.programLocalIn(deviceId, segmentationId, inPort, mac,
539 appId, type);
540 }
541
542 private void programTunnelOuts(Iterable<Device> devices,
543 IpAddress ipAddress,
544 SegmentationId segmentationId,
545 MacAddress dstMac,
546 Objective.Operation type) {
jiangruic69a7fd2015-11-19 15:40:01 +0800547 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800548 Sets.newHashSet(devices).stream()
jiangruic69a7fd2015-11-19 15:40:01 +0800549 .filter(d -> d.type() == Device.Type.CONTROLLER)
550 .filter(d -> !("ovsdb:" + ipAddress).equals(d.id().toString()))
551 .forEach(d -> {
lishuai6c56f5e2015-11-17 16:38:19 +0800552 DriverHandler handler = driverService.createHandler(d.id());
553 BridgeConfig bridgeConfig = handler
554 .behaviour(BridgeConfig.class);
555 Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
556 .getBridges();
557 Set<PortNumber> ports = bridgeConfig.getPortNumbers();
558 Iterator<BridgeDescription> it = bridgeDescriptions
559 .iterator();
560 if (it.hasNext()) {
561 BridgeDescription sw = it.next();
562 ports.stream()
563 .filter(p -> p.name()
564 .equalsIgnoreCase(tunnelName))
565 .forEach(p -> {
566 l2ForwardService.programTunnelOut(sw.deviceId(),
567 segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800568 dstMac, type, ipAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800569 });
570 }
571 });
572 }
573
574 private class InnerDeviceListener implements DeviceListener {
575
576 @Override
577 public void event(DeviceEvent event) {
578 Device device = event.subject();
579 if (Device.Type.CONTROLLER == device.type()) {
580 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
581 onControllerDetected(device);
582 }
583 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
584 if (deviceService.isAvailable(device.id())) {
585 onControllerDetected(device);
586 } else {
587 onControllerVanished(device);
588 }
589 }
590 } else if (Device.Type.SWITCH == device.type()) {
591 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
592 onOvsDetected(device);
593 }
594 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
595 if (deviceService.isAvailable(device.id())) {
596 onOvsDetected(device);
597 } else {
598 onOvsVanished(device);
599 }
600 }
601 } else {
602 log.info("Do nothing for this device type");
603 }
604 }
605 }
606
607 private class InnerHostListener implements HostListener {
608
609 @Override
610 public void event(HostEvent event) {
611 Host host = event.subject();
612 if (HostEvent.Type.HOST_ADDED == event.type()) {
613 onHostDetected(host);
614 } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
615 onHostVanished(host);
616 } else if (HostEvent.Type.HOST_UPDATED == event.type()) {
617 onHostVanished(host);
618 onHostDetected(host);
619 }
620 }
621
622 }
623
624 // Local Host Ports of Network.
625 private class NetworkOfLocalHostPorts {
626 private final Map<TenantNetworkId, Set<PortNumber>> networkOfLocalHostPorts =
627 new HashMap<TenantNetworkId, Set<PortNumber>>();
628
629 public Map<TenantNetworkId, Set<PortNumber>> getNetworkOfLocalHostPorts() {
630 return networkOfLocalHostPorts;
631 }
632 }
633
jiangruic69a7fd2015-11-19 15:40:01 +0800634 private void programGroupTable(DeviceId deviceId, ApplicationId appid,
635 PortNumber portNumber, Iterable<Device> devices, Objective.Operation type) {
636 if (type.equals(Objective.Operation.REMOVE)) {
637 return;
638 }
639
640 List<GroupBucket> buckets = Lists.newArrayList();
641 Sets.newHashSet(devices)
642 .stream()
643 .filter(d -> d.type() == Device.Type.CONTROLLER)
644 .filter(d -> !deviceId.equals(d.id()))
645 .forEach(d -> {
646 String ipAddress = d.annotations()
647 .value(CONTROLLER_IP_KEY);
648 Ip4Address dst = Ip4Address.valueOf(ipAddress);
649 Builder builder = DefaultTrafficTreatment.builder();
650
651 DriverHandler handler = driverService.createHandler(deviceId);
652 ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
653 ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
654 try {
655 treatment.setPropertyValue("tunnelDst", dst);
656 } catch (Exception e) {
657 log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
658 }
659
660 builder.extension(treatment, deviceId);
661 builder.setOutput(portNumber);
662 GroupBucket bucket = DefaultGroupBucket
663 .createAllGroupBucket(builder.build());
664 buckets.add(bucket);
665 });
666 final GroupKey key = new DefaultGroupKey(APP_ID.getBytes());
667 GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
668 GroupDescription.Type.ALL,
669 new GroupBuckets(buckets),
670 key,
671 L2ForwardServiceImpl.GROUP_ID,
672 appid);
673 groupService.addGroup(groupDescription);
674 }
lishuai858efd32015-12-04 14:30:36 +0800675
676 private class VtnL3EventListener implements VtnRscListener {
677 @Override
678 public void event(VtnRscEvent event) {
679 VtnRscEventFeedback l3Feedback = event.subject();
680 if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
681 onRouterInterfaceDetected(l3Feedback);
682 } else
683 if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
684 onRouterInterfaceVanished(l3Feedback);
685 } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) {
686 onFloatingIpDetected(l3Feedback);
687 } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) {
688 onFloatingIpVanished(l3Feedback);
689 }
690 }
691
692 }
693
694 @Override
695 public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) {
696 Objective.Operation operation = Objective.Operation.ADD;
697 RouterInterface routerInf = l3Feedback.routerInterface();
698 Iterable<RouterInterface> interfaces = routerInterfaceService
699 .getRouterInterfaces();
700 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
701 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
702 .collect(Collectors.toSet());
703 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
704 programRouterInterface(routerInf, operation);
705 } else {
706 if (interfacesSet.size() >= SUBNET_NUM) {
707 programInterfacesSet(interfacesSet, operation);
708 }
709 }
710 }
711
712 @Override
713 public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) {
714 Objective.Operation operation = Objective.Operation.REMOVE;
715 RouterInterface routerInf = l3Feedback.routerInterface();
716 Iterable<RouterInterface> interfaces = routerInterfaceService
717 .getRouterInterfaces();
718 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
719 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
720 .collect(Collectors.toSet());
721 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
722 programRouterInterface(routerInf, operation);
723 if (interfacesSet.size() == 1) {
724 routerInfFlagOfTenant.remove(routerInf.tenantId());
725 interfacesSet.stream().forEach(r -> {
726 programRouterInterface(r, operation);
727 });
728 }
729 }
730 }
731
732 @Override
733 public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
734 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT);
735 }
736
737 @Override
738 public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
739 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE);
740 }
741
742 private void programInterfacesSet(Set<RouterInterface> interfacesSet,
743 Objective.Operation operation) {
744 int subnetVmNum = 0;
745 for (RouterInterface r : interfacesSet) {
746 // Get all the host of the subnet
747 Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId());
748 if (hosts.size() > 0) {
749 subnetVmNum++;
750 if (subnetVmNum >= SUBNET_NUM) {
751 routerInfFlagOfTenant.put(r.tenantId(), true);
752 interfacesSet.stream().forEach(f -> {
753 programRouterInterface(f, operation);
754 });
755 break;
756 }
757 }
758 }
759 }
760
761 private void programRouterInterface(RouterInterface routerInf,
762 Objective.Operation operation) {
763 SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId());
764 // Get all the host of the subnet
765 Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId());
766 hosts.values().stream().forEach(h -> {
767 applyEastWestL3Flows(h, l3vni, operation);
768 });
769 }
770
771 private void applyEastWestL3Flows(Host h, SegmentationId l3vni,
772 Objective.Operation operation) {
773 if (!mastershipService.isLocalMaster(h.location().deviceId())) {
774 log.debug("not master device:{}", h.location().deviceId());
775 return;
776 }
777 String ifaceId = h.annotations().value(IFACEID);
778 VirtualPort hPort = virtualPortService
779 .getPort(VirtualPortId.portId(ifaceId));
780 if (hPort == null) {
781 hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId));
782 }
783 IpAddress srcIp = null;
784 IpAddress srcGwIp = null;
785 MacAddress srcVmGwMac = null;
786 SubnetId srcSubnetId = null;
787 Iterator<FixedIp> srcIps = hPort.fixedIps().iterator();
788 if (srcIps.hasNext()) {
789 FixedIp fixedIp = srcIps.next();
790 srcIp = fixedIp.ip();
791 srcSubnetId = fixedIp.subnetId();
792 srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp();
793 FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp);
794 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
795 if (gwPort == null) {
796 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
797 }
798 srcVmGwMac = gwPort.macAddress();
799 }
800 TenantNetwork network = tenantNetworkService
801 .getNetwork(hPort.networkId());
802 // Classifier rules
803 classifierService
804 .programL3InPortClassifierRules(h.location().deviceId(),
805 h.location().port(), h.mac(),
806 srcVmGwMac, l3vni, operation);
807 // Arp rules
808 if (operation == Objective.Operation.ADD) {
809 classifierService.programArpClassifierRules(h.location().deviceId(),
810 srcGwIp,
811 network.segmentationId(),
812 operation);
813 DriverHandler handler = driverService.createHandler(h.location().deviceId());
814 arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
815 network.segmentationId(), srcVmGwMac,
816 operation);
817 }
818 Iterable<Device> devices = deviceService.getAvailableDevices();
819 IpAddress srcArpIp = srcIp;
820 MacAddress srcArpGwMac = srcVmGwMac;
821 Sets.newHashSet(devices).stream()
822 .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> {
823 // L3FWD rules
824 l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp,
825 network.segmentationId(),
826 srcArpGwMac, h.mac(),
827 operation);
828 });
829 }
830
831 private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback,
832 VtnRscEvent.Type type) {
833 FloatingIp floaingIp = l3Feedback.floatingIp();
834 if (floaingIp != null) {
835 VirtualPortId vmPortId = floaingIp.portId();
836 VirtualPort vmPort = virtualPortService.getPort(vmPortId);
837 VirtualPort fipPort = virtualPortService
838 .getPort(floaingIp.networkId(), floaingIp.floatingIp());
839 if (vmPort == null) {
840 vmPort = VtnData.getPort(vPortStore, vmPortId);
841 }
842 if (fipPort == null) {
843 fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(),
844 floaingIp.floatingIp());
845 }
846 Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
847 Host host = null;
848 for (Host h : hostSet) {
849 String ifaceid = h.annotations().value(IFACEID);
850 if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
851 host = h;
852 break;
853 }
854 }
855 if (host != null && vmPort != null && fipPort != null) {
856 DeviceId deviceId = host.location().deviceId();
857 Port exPort = exPortOfDevice.get(deviceId);
858 SegmentationId l3vni = vtnRscService
859 .getL3vni(vmPort.tenantId());
860 // Floating ip BIND
861 if (type == VtnRscEvent.Type.FLOATINGIP_PUT) {
862 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
863 floaingIp, l3vni, exPort,
864 Objective.Operation.ADD);
865 } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) {
866 // Floating ip UNBIND
867 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
868 floaingIp, l3vni, exPort,
869 Objective.Operation.REMOVE);
870 }
871 }
872 }
873 }
874
875 private void applyNorthSouthL3Flows(DeviceId deviceId, Host host,
876 VirtualPort vmPort, VirtualPort fipPort,
877 FloatingIp floatingIp,
878 SegmentationId l3Vni, Port exPort,
879 Objective.Operation operation) {
880 if (!mastershipService.isLocalMaster(deviceId)) {
881 log.debug("not master device:{}", deviceId);
882 return;
883 }
884 List gwIpMac = getGwIpAndMac(vmPort);
885 IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
886 MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
887 FixedIp fixedGwIp = getGwFixedIp(floatingIp);
888 MacAddress fGwMac = null;
889 if (fixedGwIp != null) {
890 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
891 if (gwPort == null) {
892 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
893 }
894 fGwMac = gwPort.macAddress();
895 }
896 TenantNetwork vmNetwork = tenantNetworkService
897 .getNetwork(vmPort.networkId());
898 TenantNetwork fipNetwork = tenantNetworkService
899 .getNetwork(fipPort.networkId());
900 // L3 downlink traffic flow
901 MacAddress exPortMac = MacAddress.valueOf(exPort.annotations().value(PORT_MAC));
902 classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
903 fipNetwork.segmentationId(),
904 operation);
905 classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
906 floatingIp.floatingIp(), operation);
907 DriverHandler handler = driverService.createHandler(deviceId);
908 arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
909 fipNetwork.segmentationId(), exPortMac,
910 operation);
911 dnatService.programRules(deviceId, floatingIp.floatingIp(),
912 fGwMac, floatingIp.fixedIp(),
913 l3Vni, operation);
914 l3ForwardService
915 .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(),
916 vmNetwork.segmentationId(), dstVmGwMac,
917 vmPort.macAddress(), operation);
918
919 // L3 uplink traffic flow
920 classifierService.programL3InPortClassifierRules(deviceId,
921 host.location().port(),
922 host.mac(), dstVmGwMac,
923 l3Vni, operation);
924 snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(),
925 fGwMac, exPortMac,
926 floatingIp.floatingIp(),
927 fipNetwork.segmentationId(), operation);
928 if (operation == Objective.Operation.ADD) {
929 classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
930 vmNetwork.segmentationId(),
931 operation);
932 arpService.programArpRules(handler, deviceId, dstVmGwIp,
933 vmNetwork.segmentationId(), dstVmGwMac,
934 operation);
935 l2ForwardService.programLocalOut(deviceId,
936 fipNetwork.segmentationId(),
937 exPort.number(), fGwMac, operation);
938 }
939 }
940
941 private Port getExPort(DeviceId deviceId) {
942 List<Port> ports = deviceService.getPorts(deviceId);
943 Port exPort = null;
944 for (Port port : ports) {
945 String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
946 if (portName != null && portName.equals(EX_PORT_NAME)) {
947 exPort = port;
948 break;
949 }
950 }
951 return exPort;
952 }
953
954 private List getGwIpAndMac(VirtualPort port) {
955 List list = new ArrayList();
956 MacAddress gwMac = null;
957 SubnetId subnetId = null;
958 IpAddress gwIp = null;
959 Iterator<FixedIp> fixips = port.fixedIps().iterator();
960 if (fixips.hasNext()) {
961 FixedIp fixip = fixips.next();
962 subnetId = fixip.subnetId();
963 gwIp = subnetService.getSubnet(subnetId).gatewayIp();
964 FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp);
965 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
966 if (gwPort == null) {
967 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
968 }
969 gwMac = gwPort.macAddress();
970 }
971 list.add(gwIp);
972 list.add(gwMac);
973 return list;
974 }
975
976 private FixedIp getGwFixedIp(FloatingIp floatingIp) {
977 RouterId routerId = floatingIp.routerId();
978 Router router = routerService.getRouter(routerId);
979 RouterGateway routerGateway = router.externalGatewayInfo();
980 Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps();
981 FixedIp fixedGwIp = null;
982 if (externalFixedIps != null) {
983 Iterator<FixedIp> exFixedIps = externalFixedIps.iterator();
984 if (exFixedIps.hasNext()) {
985 fixedGwIp = exFixedIps.next();
986 }
987 }
988 return fixedGwIp;
989 }
990
991 private void applyHostMonitoredL3Rules(Host host,
992 Objective.Operation operation) {
993 String ifaceId = host.annotations().value(IFACEID);
994 DeviceId deviceId = host.location().deviceId();
995 VirtualPortId portId = VirtualPortId.portId(ifaceId);
996 VirtualPort port = virtualPortService.getPort(portId);
997 if (port == null) {
998 port = VtnData.getPort(vPortStore, portId);
999 }
1000 TenantId tenantId = port.tenantId();
1001 Port exPort = exPortOfDevice.get(deviceId);
1002 SegmentationId l3vni = vtnRscService.getL3vni(tenantId);
1003 Iterator<FixedIp> fixips = port.fixedIps().iterator();
1004 SubnetId sid = null;
1005 IpAddress hostIp = null;
1006 if (fixips.hasNext()) {
1007 FixedIp fixip = fixips.next();
1008 sid = fixip.subnetId();
1009 hostIp = fixip.ip();
1010 }
1011 final SubnetId subnetId = sid;
1012 // L3 internal network access to each other
1013 Iterable<RouterInterface> interfaces = routerInterfaceService
1014 .getRouterInterfaces();
1015 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
1016 .stream().filter(r -> r.tenantId().equals(tenantId))
1017 .collect(Collectors.toSet());
1018 long count = interfacesSet.stream()
1019 .filter(r -> !r.subnetId().equals(subnetId)).count();
1020 if (count > 0) {
1021 if (operation == Objective.Operation.ADD) {
1022 if (routerInfFlagOfTenant.get(tenantId) != null) {
1023 applyEastWestL3Flows(host, l3vni, operation);
1024 } else {
1025 if (interfacesSet.size() > 1) {
1026 programInterfacesSet(interfacesSet, operation);
1027 }
1028 }
1029 } else if (operation == Objective.Operation.REMOVE) {
1030 if (routerInfFlagOfTenant.get(tenantId) != null) {
1031 applyEastWestL3Flows(host, l3vni, operation);
1032 }
1033 }
1034 }
1035 // L3 external and internal network access to each other
1036 FloatingIp floatingIp = null;
1037 Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps();
1038 Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream()
1039 .filter(f -> f.tenantId().equals(tenantId))
1040 .collect(Collectors.toSet());
1041 for (FloatingIp f : floatingIpSet) {
1042 IpAddress fixedIp = f.fixedIp();
1043 if (fixedIp.equals(hostIp)) {
1044 floatingIp = f;
1045 break;
1046 }
1047 }
1048 if (floatingIp != null) {
1049 VirtualPort fipPort = virtualPortService
1050 .getPort(floatingIp.networkId(), floatingIp.floatingIp());
1051 if (fipPort == null) {
1052 fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(),
1053 floatingIp.floatingIp());
1054 }
1055 applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp,
1056 l3vni, exPort, operation);
1057 }
1058 }
lishuai6c56f5e2015-11-17 16:38:19 +08001059}