blob: 5b137c885b074d5a01531f1d085021f3e0bec446 [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 int SUBNET_NUM = 2;
lishuai6c56f5e2015-11-17 16:38:19 +0800205
lishuai7dc63d92015-11-27 17:15:25 +0800206 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
lishuai6c56f5e2015-11-17 16:38:19 +0800207 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
jiangruic69a7fd2015-11-19 15:40:01 +0800208 private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
lishuai858efd32015-12-04 14:30:36 +0800209 private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet;
210 private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant;
211 private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice;
lishuai6c56f5e2015-11-17 16:38:19 +0800212
213 @Activate
214 public void activate() {
215 appId = coreService.registerApplication(APP_ID);
216 classifierService = new ClassifierServiceImpl(appId);
217 l2ForwardService = new L2ForwardServiceImpl(appId);
218
219 deviceService.addListener(deviceListener);
220 hostService.addListener(hostListener);
221
222 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
223 .register(KryoNamespaces.API)
224 .register(NetworkOfLocalHostPorts.class)
225 .register(TenantNetworkId.class)
226 .register(Host.class)
227 .register(TenantNetwork.class)
228 .register(TenantId.class)
lishuai7dc63d92015-11-27 17:15:25 +0800229 .register(SubnetId.class)
230 .register(VirtualPortId.class)
231 .register(VirtualPort.State.class)
232 .register(AllowedAddressPair.class)
233 .register(FixedIp.class)
234 .register(BindingHostId.class)
235 .register(SecurityGroup.class)
236 .register(IpAddress.class)
237 .register(DefaultVirtualPort.class);
238
239 vPortStore = storageService
240 .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder()
241 .withName(VIRTUALPORT).withSerializer(serializer)
242 .withTimestampProvider((k, v) -> clockService.getTimestamp())
243 .build();
lishuai6c56f5e2015-11-17 16:38:19 +0800244
245 switchesOfController = storageService
246 .<IpAddress, Boolean>eventuallyConsistentMapBuilder()
247 .withName(SWITCHES_OF_CONTROLLER).withSerializer(serializer)
248 .withTimestampProvider((k, v) -> clockService.getTimestamp())
249 .build();
250
251 switchOfLocalHostPorts = storageService
jiangruic69a7fd2015-11-19 15:40:01 +0800252 .<DeviceId, NetworkOfLocalHostPorts>eventuallyConsistentMapBuilder()
253 .withName(SWITCH_OF_LOCAL_HOST_PORTS).withSerializer(serializer)
254 .withTimestampProvider((k, v) -> clockService.getTimestamp())
lishuai6c56f5e2015-11-17 16:38:19 +0800255 .build();
256
lishuai858efd32015-12-04 14:30:36 +0800257 hostsOfSubnet = storageService
258 .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder()
259 .withName(HOSTS_OF_SUBNET).withSerializer(serializer)
260 .withTimestampProvider((k, v) -> clockService.getTimestamp())
261 .build();
262
263 routerInfFlagOfTenant = storageService
264 .<TenantId, Boolean>eventuallyConsistentMapBuilder()
265 .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer)
266 .withTimestampProvider((k, v) -> clockService.getTimestamp())
267 .build();
268
269 exPortOfDevice = storageService
270 .<DeviceId, Port>eventuallyConsistentMapBuilder()
271 .withName(EX_PORT_OF_DEVICE).withSerializer(serializer)
272 .withTimestampProvider((k, v) -> clockService.getTimestamp())
273 .build();
274
lishuai6c56f5e2015-11-17 16:38:19 +0800275 log.info("Started");
276 }
277
278 @Deactivate
279 public void deactivate() {
280 deviceService.removeListener(deviceListener);
281 hostService.removeListener(hostListener);
lishuai858efd32015-12-04 14:30:36 +0800282 vtnRscService.removeListener(l3EventListener);
lishuai6c56f5e2015-11-17 16:38:19 +0800283 log.info("Stopped");
284 }
285
286 @Override
287 public void onControllerDetected(Device controllerDevice) {
288 if (controllerDevice == null) {
289 log.error("The controller device is null");
290 return;
291 }
292 String localIpAddress = controllerDevice.annotations()
293 .value(CONTROLLER_IP_KEY);
294 IpAddress localIp = IpAddress.valueOf(localIpAddress);
295 DeviceId controllerDeviceId = controllerDevice.id();
296 DriverHandler handler = driverService.createHandler(controllerDeviceId);
297 if (mastershipService.isLocalMaster(controllerDeviceId)) {
298 // Get DataPathIdGenerator
299 String ipaddress = controllerDevice.annotations().value("ipaddress");
300 DataPathIdGenerator dpidGenerator = DataPathIdGenerator.builder()
301 .addIpAddress(ipaddress).build();
302 DeviceId deviceId = dpidGenerator.getDeviceId();
303 String dpid = dpidGenerator.getDpId();
304 // Inject pipeline driver name
305 BasicDeviceConfig config = configService.addConfig(deviceId,
306 BasicDeviceConfig.class);
307 config.driver(DRIVER_NAME);
308 configService.applyConfig(deviceId, BasicDeviceConfig.class, config.node());
309 // Add Bridge
310 VtnConfig.applyBridgeConfig(handler, dpid, EX_PORT_NAME);
311 log.info("A new ovs is created in node {}", localIp.toString());
312 switchesOfController.put(localIp, true);
313 }
314 // Create tunnel in br-int on all controllers
315 programTunnelConfig(controllerDeviceId, localIp, handler);
316 }
317
318 @Override
319 public void onControllerVanished(Device controllerDevice) {
320 if (controllerDevice == null) {
321 log.error("The device is null");
322 return;
323 }
324 String dstIp = controllerDevice.annotations().value(CONTROLLER_IP_KEY);
325 IpAddress dstIpAddress = IpAddress.valueOf(dstIp);
326 DeviceId controllerDeviceId = controllerDevice.id();
327 if (mastershipService.isLocalMaster(controllerDeviceId)) {
328 switchesOfController.remove(dstIpAddress);
329 }
330 // remove tunnel in br-int on other controllers
331 programTunnelConfig(controllerDeviceId, dstIpAddress, null);
332 }
333
334 @Override
335 public void onOvsDetected(Device device) {
336 // Create tunnel out flow rules
337 applyTunnelOut(device, Objective.Operation.ADD);
338 }
339
340 @Override
341 public void onOvsVanished(Device device) {
342 // Remove Tunnel out flow rules
343 applyTunnelOut(device, Objective.Operation.REMOVE);
344 }
345
346 @Override
347 public void onHostDetected(Host host) {
lishuai858efd32015-12-04 14:30:36 +0800348 DeviceId deviceId = host.location().deviceId();
349 if (!mastershipService.isLocalMaster(deviceId)) {
350 return;
351 }
352 String ifaceId = host.annotations().value(IFACEID);
353 if (ifaceId == null) {
354 log.error("The ifaceId of Host is null");
355 return;
356 }
lishuai6c56f5e2015-11-17 16:38:19 +0800357 // apply L2 openflow rules
358 applyHostMonitoredL2Rules(host, Objective.Operation.ADD);
lishuai858efd32015-12-04 14:30:36 +0800359 // apply L3 openflow rules
360 applyHostMonitoredL3Rules(host, Objective.Operation.ADD);
lishuai6c56f5e2015-11-17 16:38:19 +0800361 }
362
363 @Override
364 public void onHostVanished(Host host) {
lishuai858efd32015-12-04 14:30:36 +0800365 DeviceId deviceId = host.location().deviceId();
366 if (!mastershipService.isLocalMaster(deviceId)) {
367 return;
368 }
369 String ifaceId = host.annotations().value(IFACEID);
370 if (ifaceId == null) {
371 log.error("The ifaceId of Host is null");
372 return;
373 }
lishuai6c56f5e2015-11-17 16:38:19 +0800374 // apply L2 openflow rules
375 applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE);
lishuai858efd32015-12-04 14:30:36 +0800376 // apply L3 openflow rules
377 applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE);
lishuai6c56f5e2015-11-17 16:38:19 +0800378 }
379
380 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
381 DriverHandler localHandler) {
jiangruic69a7fd2015-11-19 15:40:01 +0800382 if (mastershipService.isLocalMaster(localDeviceId)) {
383 VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP));
384 log.info("Add tunnel on {}", localIp);
385 }
lishuai6c56f5e2015-11-17 16:38:19 +0800386 }
387
388 private void applyTunnelOut(Device device, Objective.Operation type) {
389 if (device == null) {
390 log.error("The device is null");
391 return;
392 }
393 if (!mastershipService.isLocalMaster(device.id())) {
394 return;
395 }
396 String controllerIp = VtnData.getControllerIpOfSwitch(device);
397 if (controllerIp == null) {
398 log.error("Can't find controller of device: {}",
399 device.id().toString());
400 return;
401 }
402 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
403 if (!switchesOfController.containsKey(ipAddress)) {
404 log.error("Can't find controller of device: {}",
405 device.id().toString());
406 return;
407 }
408 if (type == Objective.Operation.ADD) {
lishuaia3e32342015-12-07 10:59:17 +0800409 // Save external port
410 Port export = getExPort(device.id());
411 exPortOfDevice.put(device.id(), export);
lishuai6c56f5e2015-11-17 16:38:19 +0800412 switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts());
413 } else if (type == Objective.Operation.REMOVE) {
lishuaia3e32342015-12-07 10:59:17 +0800414 exPortOfDevice.remove(device.id());
lishuai6c56f5e2015-11-17 16:38:19 +0800415 switchOfLocalHostPorts.remove(device.id());
416 }
417 Iterable<Device> devices = deviceService.getAvailableDevices();
418 DeviceId localControllerId = VtnData.getControllerId(device, devices);
419 DriverHandler handler = driverService.createHandler(localControllerId);
420 Set<PortNumber> ports = VtnConfig.getPortNumbers(handler);
421 Iterable<Host> allHosts = hostService.getHosts();
jiangruic69a7fd2015-11-19 15:40:01 +0800422 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800423 if (allHosts != null) {
424 Sets.newHashSet(allHosts).stream().forEach(host -> {
425 MacAddress hostMac = host.mac();
426 String ifaceId = host.annotations().value(IFACEID);
427 if (ifaceId == null) {
428 log.error("The ifaceId of Host is null");
429 return;
430 }
431 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
432 VirtualPort virtualPort = virtualPortService
433 .getPort(virtualPortId);
434 TenantNetwork network = tenantNetworkService
435 .getNetwork(virtualPort.networkId());
436 SegmentationId segmentationId = network.segmentationId();
437 DeviceId remoteDeviceId = host.location().deviceId();
438 Device remoteDevice = deviceService.getDevice(remoteDeviceId);
439 String remoteControllerIp = VtnData
440 .getControllerIpOfSwitch(remoteDevice);
441 if (remoteControllerIp == null) {
442 log.error("Can't find remote controller of device: {}",
443 remoteDeviceId.toString());
444 return;
445 }
446 IpAddress remoteIpAddress = IpAddress
447 .valueOf(remoteControllerIp);
lishuai6c56f5e2015-11-17 16:38:19 +0800448 ports.stream()
449 .filter(p -> p.name().equalsIgnoreCase(tunnelName))
450 .forEach(p -> {
451 l2ForwardService
452 .programTunnelOut(device.id(), segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800453 hostMac, type, remoteIpAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800454 });
455 });
456 }
457 }
458
459 private void applyHostMonitoredL2Rules(Host host, Objective.Operation type) {
460 DeviceId deviceId = host.location().deviceId();
461 if (!mastershipService.isLocalMaster(deviceId)) {
462 return;
463 }
464 String ifaceId = host.annotations().value(IFACEID);
465 if (ifaceId == null) {
466 log.error("The ifaceId of Host is null");
467 return;
468 }
469 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
470 VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
471 if (virtualPort == null) {
lishuai858efd32015-12-04 14:30:36 +0800472 virtualPort = VtnData.getPort(vPortStore, virtualPortId);
lishuai6c56f5e2015-11-17 16:38:19 +0800473 }
474
475 Iterable<Device> devices = deviceService.getAvailableDevices();
476 PortNumber inPort = host.location().port();
477 MacAddress mac = host.mac();
478 Device device = deviceService.getDevice(deviceId);
479 String controllerIp = VtnData.getControllerIpOfSwitch(device);
480 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
481 TenantNetwork network = tenantNetworkService.getNetwork(virtualPort.networkId());
482 if (network == null) {
483 log.error("Can't find network of the host");
484 return;
485 }
486 SegmentationId segmentationId = network.segmentationId();
487 // Get all the tunnel PortNumber in the current node
488 Iterable<Port> ports = deviceService.getPorts(deviceId);
489 Collection<PortNumber> localTunnelPorts = VtnData.getLocalTunnelPorts(ports);
490 // Get all the local vm's PortNumber in the current node
491 Map<TenantNetworkId, Set<PortNumber>> localHostPorts = switchOfLocalHostPorts
jiangruic69a7fd2015-11-19 15:40:01 +0800492 .get(deviceId).getNetworkOfLocalHostPorts();
lishuai6c56f5e2015-11-17 16:38:19 +0800493 Set<PortNumber> networkOflocalHostPorts = localHostPorts.get(network.id());
jiangruic69a7fd2015-11-19 15:40:01 +0800494 for (PortNumber p : localTunnelPorts) {
495 programGroupTable(deviceId, appId, p, devices, type);
496 }
lishuai6c56f5e2015-11-17 16:38:19 +0800497
498 if (type == Objective.Operation.ADD) {
lishuai7dc63d92015-11-27 17:15:25 +0800499 vPortStore.put(virtualPortId, virtualPort);
lishuai6c56f5e2015-11-17 16:38:19 +0800500 if (networkOflocalHostPorts == null) {
501 networkOflocalHostPorts = new HashSet<PortNumber>();
502 localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts);
503 }
504 networkOflocalHostPorts.add(inPort);
jiangruic69a7fd2015-11-19 15:40:01 +0800505 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
506 inPort, networkOflocalHostPorts,
507 localTunnelPorts,
508 type);
lishuai6c56f5e2015-11-17 16:38:19 +0800509 classifierService.programTunnelIn(deviceId, segmentationId,
510 localTunnelPorts,
511 type);
512 } else if (type == Objective.Operation.REMOVE) {
lishuai7dc63d92015-11-27 17:15:25 +0800513 vPortStore.remove(virtualPortId);
jiangruic69a7fd2015-11-19 15:40:01 +0800514 if (networkOflocalHostPorts != null) {
515 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
516 inPort, networkOflocalHostPorts,
517 localTunnelPorts,
518 type);
519 networkOflocalHostPorts.remove(inPort);
520 if (networkOflocalHostPorts.isEmpty()) {
521 classifierService.programTunnelIn(deviceId, segmentationId,
522 localTunnelPorts,
523 type);
524 switchOfLocalHostPorts.get(deviceId).getNetworkOfLocalHostPorts()
525 .remove(virtualPort.networkId());
526 }
lishuai6c56f5e2015-11-17 16:38:19 +0800527 }
528 }
529
jiangruic69a7fd2015-11-19 15:40:01 +0800530 l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac,
531 type);
532
lishuai6c56f5e2015-11-17 16:38:19 +0800533 l2ForwardService.programTunnelBcastRules(deviceId, segmentationId,
534 networkOflocalHostPorts,
535 localTunnelPorts,
536 type);
537
538 programTunnelOuts(devices, ipAddress, segmentationId, mac,
539 type);
540
541 classifierService.programLocalIn(deviceId, segmentationId, inPort, mac,
542 appId, type);
543 }
544
545 private void programTunnelOuts(Iterable<Device> devices,
546 IpAddress ipAddress,
547 SegmentationId segmentationId,
548 MacAddress dstMac,
549 Objective.Operation type) {
jiangruic69a7fd2015-11-19 15:40:01 +0800550 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800551 Sets.newHashSet(devices).stream()
jiangruic69a7fd2015-11-19 15:40:01 +0800552 .filter(d -> d.type() == Device.Type.CONTROLLER)
553 .filter(d -> !("ovsdb:" + ipAddress).equals(d.id().toString()))
554 .forEach(d -> {
lishuai6c56f5e2015-11-17 16:38:19 +0800555 DriverHandler handler = driverService.createHandler(d.id());
556 BridgeConfig bridgeConfig = handler
557 .behaviour(BridgeConfig.class);
558 Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
559 .getBridges();
560 Set<PortNumber> ports = bridgeConfig.getPortNumbers();
561 Iterator<BridgeDescription> it = bridgeDescriptions
562 .iterator();
563 if (it.hasNext()) {
564 BridgeDescription sw = it.next();
565 ports.stream()
566 .filter(p -> p.name()
567 .equalsIgnoreCase(tunnelName))
568 .forEach(p -> {
569 l2ForwardService.programTunnelOut(sw.deviceId(),
570 segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800571 dstMac, type, ipAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800572 });
573 }
574 });
575 }
576
577 private class InnerDeviceListener implements DeviceListener {
578
579 @Override
580 public void event(DeviceEvent event) {
581 Device device = event.subject();
582 if (Device.Type.CONTROLLER == device.type()) {
583 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
584 onControllerDetected(device);
585 }
586 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
587 if (deviceService.isAvailable(device.id())) {
588 onControllerDetected(device);
589 } else {
590 onControllerVanished(device);
591 }
592 }
593 } else if (Device.Type.SWITCH == device.type()) {
594 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
595 onOvsDetected(device);
596 }
597 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
598 if (deviceService.isAvailable(device.id())) {
599 onOvsDetected(device);
600 } else {
601 onOvsVanished(device);
602 }
603 }
604 } else {
605 log.info("Do nothing for this device type");
606 }
607 }
608 }
609
610 private class InnerHostListener implements HostListener {
611
612 @Override
613 public void event(HostEvent event) {
614 Host host = event.subject();
615 if (HostEvent.Type.HOST_ADDED == event.type()) {
616 onHostDetected(host);
617 } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
618 onHostVanished(host);
619 } else if (HostEvent.Type.HOST_UPDATED == event.type()) {
620 onHostVanished(host);
621 onHostDetected(host);
622 }
623 }
624
625 }
626
627 // Local Host Ports of Network.
628 private class NetworkOfLocalHostPorts {
629 private final Map<TenantNetworkId, Set<PortNumber>> networkOfLocalHostPorts =
630 new HashMap<TenantNetworkId, Set<PortNumber>>();
631
632 public Map<TenantNetworkId, Set<PortNumber>> getNetworkOfLocalHostPorts() {
633 return networkOfLocalHostPorts;
634 }
635 }
636
jiangruic69a7fd2015-11-19 15:40:01 +0800637 private void programGroupTable(DeviceId deviceId, ApplicationId appid,
638 PortNumber portNumber, Iterable<Device> devices, Objective.Operation type) {
639 if (type.equals(Objective.Operation.REMOVE)) {
640 return;
641 }
642
643 List<GroupBucket> buckets = Lists.newArrayList();
644 Sets.newHashSet(devices)
645 .stream()
646 .filter(d -> d.type() == Device.Type.CONTROLLER)
647 .filter(d -> !deviceId.equals(d.id()))
648 .forEach(d -> {
649 String ipAddress = d.annotations()
650 .value(CONTROLLER_IP_KEY);
651 Ip4Address dst = Ip4Address.valueOf(ipAddress);
652 Builder builder = DefaultTrafficTreatment.builder();
653
654 DriverHandler handler = driverService.createHandler(deviceId);
655 ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
656 ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
657 try {
658 treatment.setPropertyValue("tunnelDst", dst);
659 } catch (Exception e) {
660 log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
661 }
662
663 builder.extension(treatment, deviceId);
664 builder.setOutput(portNumber);
665 GroupBucket bucket = DefaultGroupBucket
666 .createAllGroupBucket(builder.build());
667 buckets.add(bucket);
668 });
669 final GroupKey key = new DefaultGroupKey(APP_ID.getBytes());
670 GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
671 GroupDescription.Type.ALL,
672 new GroupBuckets(buckets),
673 key,
674 L2ForwardServiceImpl.GROUP_ID,
675 appid);
676 groupService.addGroup(groupDescription);
677 }
lishuai858efd32015-12-04 14:30:36 +0800678
679 private class VtnL3EventListener implements VtnRscListener {
680 @Override
681 public void event(VtnRscEvent event) {
682 VtnRscEventFeedback l3Feedback = event.subject();
683 if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
684 onRouterInterfaceDetected(l3Feedback);
685 } else
686 if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
687 onRouterInterfaceVanished(l3Feedback);
688 } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) {
689 onFloatingIpDetected(l3Feedback);
690 } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) {
691 onFloatingIpVanished(l3Feedback);
692 }
693 }
694
695 }
696
697 @Override
698 public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) {
699 Objective.Operation operation = Objective.Operation.ADD;
700 RouterInterface routerInf = l3Feedback.routerInterface();
701 Iterable<RouterInterface> interfaces = routerInterfaceService
702 .getRouterInterfaces();
703 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
704 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
705 .collect(Collectors.toSet());
706 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
707 programRouterInterface(routerInf, operation);
708 } else {
709 if (interfacesSet.size() >= SUBNET_NUM) {
710 programInterfacesSet(interfacesSet, operation);
711 }
712 }
713 }
714
715 @Override
716 public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) {
717 Objective.Operation operation = Objective.Operation.REMOVE;
718 RouterInterface routerInf = l3Feedback.routerInterface();
719 Iterable<RouterInterface> interfaces = routerInterfaceService
720 .getRouterInterfaces();
721 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
722 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
723 .collect(Collectors.toSet());
724 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
725 programRouterInterface(routerInf, operation);
726 if (interfacesSet.size() == 1) {
727 routerInfFlagOfTenant.remove(routerInf.tenantId());
728 interfacesSet.stream().forEach(r -> {
729 programRouterInterface(r, operation);
730 });
731 }
732 }
733 }
734
735 @Override
736 public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
737 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT);
738 }
739
740 @Override
741 public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
742 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE);
743 }
744
745 private void programInterfacesSet(Set<RouterInterface> interfacesSet,
746 Objective.Operation operation) {
747 int subnetVmNum = 0;
748 for (RouterInterface r : interfacesSet) {
749 // Get all the host of the subnet
750 Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId());
751 if (hosts.size() > 0) {
752 subnetVmNum++;
753 if (subnetVmNum >= SUBNET_NUM) {
754 routerInfFlagOfTenant.put(r.tenantId(), true);
755 interfacesSet.stream().forEach(f -> {
756 programRouterInterface(f, operation);
757 });
758 break;
759 }
760 }
761 }
762 }
763
764 private void programRouterInterface(RouterInterface routerInf,
765 Objective.Operation operation) {
766 SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId());
767 // Get all the host of the subnet
768 Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId());
769 hosts.values().stream().forEach(h -> {
770 applyEastWestL3Flows(h, l3vni, operation);
771 });
772 }
773
774 private void applyEastWestL3Flows(Host h, SegmentationId l3vni,
775 Objective.Operation operation) {
776 if (!mastershipService.isLocalMaster(h.location().deviceId())) {
777 log.debug("not master device:{}", h.location().deviceId());
778 return;
779 }
780 String ifaceId = h.annotations().value(IFACEID);
781 VirtualPort hPort = virtualPortService
782 .getPort(VirtualPortId.portId(ifaceId));
783 if (hPort == null) {
784 hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId));
785 }
786 IpAddress srcIp = null;
787 IpAddress srcGwIp = null;
788 MacAddress srcVmGwMac = null;
789 SubnetId srcSubnetId = null;
790 Iterator<FixedIp> srcIps = hPort.fixedIps().iterator();
791 if (srcIps.hasNext()) {
792 FixedIp fixedIp = srcIps.next();
793 srcIp = fixedIp.ip();
794 srcSubnetId = fixedIp.subnetId();
795 srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp();
796 FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp);
797 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
798 if (gwPort == null) {
799 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
800 }
801 srcVmGwMac = gwPort.macAddress();
802 }
803 TenantNetwork network = tenantNetworkService
804 .getNetwork(hPort.networkId());
805 // Classifier rules
806 classifierService
807 .programL3InPortClassifierRules(h.location().deviceId(),
808 h.location().port(), h.mac(),
809 srcVmGwMac, l3vni, operation);
810 // Arp rules
811 if (operation == Objective.Operation.ADD) {
812 classifierService.programArpClassifierRules(h.location().deviceId(),
813 srcGwIp,
814 network.segmentationId(),
815 operation);
816 DriverHandler handler = driverService.createHandler(h.location().deviceId());
817 arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
818 network.segmentationId(), srcVmGwMac,
819 operation);
820 }
821 Iterable<Device> devices = deviceService.getAvailableDevices();
822 IpAddress srcArpIp = srcIp;
823 MacAddress srcArpGwMac = srcVmGwMac;
824 Sets.newHashSet(devices).stream()
825 .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> {
826 // L3FWD rules
827 l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp,
828 network.segmentationId(),
829 srcArpGwMac, h.mac(),
830 operation);
831 });
832 }
833
834 private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback,
835 VtnRscEvent.Type type) {
836 FloatingIp floaingIp = l3Feedback.floatingIp();
837 if (floaingIp != null) {
838 VirtualPortId vmPortId = floaingIp.portId();
839 VirtualPort vmPort = virtualPortService.getPort(vmPortId);
840 VirtualPort fipPort = virtualPortService
841 .getPort(floaingIp.networkId(), floaingIp.floatingIp());
842 if (vmPort == null) {
843 vmPort = VtnData.getPort(vPortStore, vmPortId);
844 }
845 if (fipPort == null) {
846 fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(),
847 floaingIp.floatingIp());
848 }
849 Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
850 Host host = null;
851 for (Host h : hostSet) {
852 String ifaceid = h.annotations().value(IFACEID);
853 if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
854 host = h;
855 break;
856 }
857 }
858 if (host != null && vmPort != null && fipPort != null) {
859 DeviceId deviceId = host.location().deviceId();
860 Port exPort = exPortOfDevice.get(deviceId);
861 SegmentationId l3vni = vtnRscService
862 .getL3vni(vmPort.tenantId());
863 // Floating ip BIND
864 if (type == VtnRscEvent.Type.FLOATINGIP_PUT) {
865 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
866 floaingIp, l3vni, exPort,
867 Objective.Operation.ADD);
868 } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) {
869 // Floating ip UNBIND
870 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
871 floaingIp, l3vni, exPort,
872 Objective.Operation.REMOVE);
873 }
874 }
875 }
876 }
877
878 private void applyNorthSouthL3Flows(DeviceId deviceId, Host host,
879 VirtualPort vmPort, VirtualPort fipPort,
880 FloatingIp floatingIp,
881 SegmentationId l3Vni, Port exPort,
882 Objective.Operation operation) {
883 if (!mastershipService.isLocalMaster(deviceId)) {
884 log.debug("not master device:{}", deviceId);
885 return;
886 }
887 List gwIpMac = getGwIpAndMac(vmPort);
888 IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
889 MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
890 FixedIp fixedGwIp = getGwFixedIp(floatingIp);
891 MacAddress fGwMac = null;
892 if (fixedGwIp != null) {
893 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
894 if (gwPort == null) {
895 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
896 }
897 fGwMac = gwPort.macAddress();
898 }
899 TenantNetwork vmNetwork = tenantNetworkService
900 .getNetwork(vmPort.networkId());
901 TenantNetwork fipNetwork = tenantNetworkService
902 .getNetwork(fipPort.networkId());
903 // L3 downlink traffic flow
lishuaia3e32342015-12-07 10:59:17 +0800904 MacAddress exPortMac = MacAddress.valueOf(exPort.annotations()
905 .value(AnnotationKeys.PORT_MAC));
lishuai858efd32015-12-04 14:30:36 +0800906 classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
907 fipNetwork.segmentationId(),
908 operation);
909 classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
910 floatingIp.floatingIp(), operation);
911 DriverHandler handler = driverService.createHandler(deviceId);
912 arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
913 fipNetwork.segmentationId(), exPortMac,
914 operation);
915 dnatService.programRules(deviceId, floatingIp.floatingIp(),
916 fGwMac, floatingIp.fixedIp(),
917 l3Vni, operation);
918 l3ForwardService
919 .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(),
920 vmNetwork.segmentationId(), dstVmGwMac,
921 vmPort.macAddress(), operation);
922
923 // L3 uplink traffic flow
924 classifierService.programL3InPortClassifierRules(deviceId,
925 host.location().port(),
926 host.mac(), dstVmGwMac,
927 l3Vni, operation);
928 snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(),
929 fGwMac, exPortMac,
930 floatingIp.floatingIp(),
931 fipNetwork.segmentationId(), operation);
932 if (operation == Objective.Operation.ADD) {
933 classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
934 vmNetwork.segmentationId(),
935 operation);
936 arpService.programArpRules(handler, deviceId, dstVmGwIp,
937 vmNetwork.segmentationId(), dstVmGwMac,
938 operation);
939 l2ForwardService.programLocalOut(deviceId,
940 fipNetwork.segmentationId(),
941 exPort.number(), fGwMac, operation);
942 }
943 }
944
945 private Port getExPort(DeviceId deviceId) {
946 List<Port> ports = deviceService.getPorts(deviceId);
947 Port exPort = null;
948 for (Port port : ports) {
949 String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
950 if (portName != null && portName.equals(EX_PORT_NAME)) {
951 exPort = port;
952 break;
953 }
954 }
955 return exPort;
956 }
957
958 private List getGwIpAndMac(VirtualPort port) {
959 List list = new ArrayList();
960 MacAddress gwMac = null;
961 SubnetId subnetId = null;
962 IpAddress gwIp = null;
963 Iterator<FixedIp> fixips = port.fixedIps().iterator();
964 if (fixips.hasNext()) {
965 FixedIp fixip = fixips.next();
966 subnetId = fixip.subnetId();
967 gwIp = subnetService.getSubnet(subnetId).gatewayIp();
968 FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp);
969 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
970 if (gwPort == null) {
971 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
972 }
973 gwMac = gwPort.macAddress();
974 }
975 list.add(gwIp);
976 list.add(gwMac);
977 return list;
978 }
979
980 private FixedIp getGwFixedIp(FloatingIp floatingIp) {
981 RouterId routerId = floatingIp.routerId();
982 Router router = routerService.getRouter(routerId);
983 RouterGateway routerGateway = router.externalGatewayInfo();
984 Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps();
985 FixedIp fixedGwIp = null;
986 if (externalFixedIps != null) {
987 Iterator<FixedIp> exFixedIps = externalFixedIps.iterator();
988 if (exFixedIps.hasNext()) {
989 fixedGwIp = exFixedIps.next();
990 }
991 }
992 return fixedGwIp;
993 }
994
995 private void applyHostMonitoredL3Rules(Host host,
996 Objective.Operation operation) {
997 String ifaceId = host.annotations().value(IFACEID);
998 DeviceId deviceId = host.location().deviceId();
999 VirtualPortId portId = VirtualPortId.portId(ifaceId);
1000 VirtualPort port = virtualPortService.getPort(portId);
1001 if (port == null) {
1002 port = VtnData.getPort(vPortStore, portId);
1003 }
1004 TenantId tenantId = port.tenantId();
1005 Port exPort = exPortOfDevice.get(deviceId);
1006 SegmentationId l3vni = vtnRscService.getL3vni(tenantId);
1007 Iterator<FixedIp> fixips = port.fixedIps().iterator();
1008 SubnetId sid = null;
1009 IpAddress hostIp = null;
1010 if (fixips.hasNext()) {
1011 FixedIp fixip = fixips.next();
1012 sid = fixip.subnetId();
1013 hostIp = fixip.ip();
1014 }
1015 final SubnetId subnetId = sid;
1016 // L3 internal network access to each other
1017 Iterable<RouterInterface> interfaces = routerInterfaceService
1018 .getRouterInterfaces();
1019 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
1020 .stream().filter(r -> r.tenantId().equals(tenantId))
1021 .collect(Collectors.toSet());
1022 long count = interfacesSet.stream()
1023 .filter(r -> !r.subnetId().equals(subnetId)).count();
1024 if (count > 0) {
1025 if (operation == Objective.Operation.ADD) {
1026 if (routerInfFlagOfTenant.get(tenantId) != null) {
1027 applyEastWestL3Flows(host, l3vni, operation);
1028 } else {
1029 if (interfacesSet.size() > 1) {
1030 programInterfacesSet(interfacesSet, operation);
1031 }
1032 }
1033 } else if (operation == Objective.Operation.REMOVE) {
1034 if (routerInfFlagOfTenant.get(tenantId) != null) {
1035 applyEastWestL3Flows(host, l3vni, operation);
1036 }
1037 }
1038 }
1039 // L3 external and internal network access to each other
1040 FloatingIp floatingIp = null;
1041 Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps();
1042 Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream()
1043 .filter(f -> f.tenantId().equals(tenantId))
1044 .collect(Collectors.toSet());
1045 for (FloatingIp f : floatingIpSet) {
1046 IpAddress fixedIp = f.fixedIp();
1047 if (fixedIp.equals(hostIp)) {
1048 floatingIp = f;
1049 break;
1050 }
1051 }
1052 if (floatingIp != null) {
1053 VirtualPort fipPort = virtualPortService
1054 .getPort(floatingIp.networkId(), floatingIp.floatingIp());
1055 if (fipPort == null) {
1056 fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(),
1057 floatingIp.floatingIp());
1058 }
1059 applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp,
1060 l3vni, exPort, operation);
1061 }
1062 }
lishuai6c56f5e2015-11-17 16:38:19 +08001063}