blob: 9213a84641b918a56c5dbd24bec0e7c8a0cf7c63 [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;
lishuai74f2d532015-12-10 17:03:34 +080029import java.util.concurrent.ConcurrentHashMap;
lishuai858efd32015-12-04 14:30:36 +080030import java.util.stream.Collectors;
lishuai6c56f5e2015-11-17 16:38:19 +080031
32import org.apache.felix.scr.annotations.Activate;
33import org.apache.felix.scr.annotations.Component;
34import org.apache.felix.scr.annotations.Deactivate;
35import org.apache.felix.scr.annotations.Reference;
36import org.apache.felix.scr.annotations.ReferenceCardinality;
37import org.apache.felix.scr.annotations.Service;
jiangruic69a7fd2015-11-19 15:40:01 +080038import org.onlab.packet.Ip4Address;
lishuai6c56f5e2015-11-17 16:38:19 +080039import org.onlab.packet.IpAddress;
40import org.onlab.packet.MacAddress;
41import org.onlab.util.KryoNamespace;
42import org.onosproject.core.ApplicationId;
43import org.onosproject.core.CoreService;
44import org.onosproject.mastership.MastershipService;
lishuai858efd32015-12-04 14:30:36 +080045import org.onosproject.net.AnnotationKeys;
lishuai6c56f5e2015-11-17 16:38:19 +080046import org.onosproject.net.Device;
47import org.onosproject.net.DeviceId;
48import org.onosproject.net.Host;
lishuai858efd32015-12-04 14:30:36 +080049import org.onosproject.net.HostId;
lishuai6c56f5e2015-11-17 16:38:19 +080050import org.onosproject.net.Port;
51import org.onosproject.net.PortNumber;
52import org.onosproject.net.behaviour.BridgeConfig;
53import org.onosproject.net.behaviour.BridgeDescription;
jiangruic69a7fd2015-11-19 15:40:01 +080054import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
lishuai6c56f5e2015-11-17 16:38:19 +080055import org.onosproject.net.config.NetworkConfigService;
56import org.onosproject.net.config.basics.BasicDeviceConfig;
57import org.onosproject.net.device.DeviceEvent;
58import org.onosproject.net.device.DeviceListener;
59import org.onosproject.net.device.DeviceService;
60import org.onosproject.net.driver.DriverHandler;
61import org.onosproject.net.driver.DriverService;
jiangruic69a7fd2015-11-19 15:40:01 +080062import org.onosproject.net.flow.DefaultTrafficTreatment;
63import org.onosproject.net.flow.TrafficTreatment.Builder;
64import org.onosproject.net.flow.instructions.ExtensionTreatment;
lishuai6c56f5e2015-11-17 16:38:19 +080065import org.onosproject.net.flowobjective.Objective;
jiangruic69a7fd2015-11-19 15:40:01 +080066import org.onosproject.net.group.DefaultGroupBucket;
67import org.onosproject.net.group.DefaultGroupDescription;
68import org.onosproject.net.group.DefaultGroupKey;
69import org.onosproject.net.group.GroupBucket;
70import org.onosproject.net.group.GroupBuckets;
71import org.onosproject.net.group.GroupDescription;
72import org.onosproject.net.group.GroupKey;
73import org.onosproject.net.group.GroupService;
lishuai6c56f5e2015-11-17 16:38:19 +080074import org.onosproject.net.host.HostEvent;
75import org.onosproject.net.host.HostListener;
76import org.onosproject.net.host.HostService;
77import org.onosproject.store.serializers.KryoNamespaces;
lishuai6c56f5e2015-11-17 16:38:19 +080078import org.onosproject.store.service.EventuallyConsistentMap;
79import org.onosproject.store.service.LogicalClockService;
lishuai6c56f5e2015-11-17 16:38:19 +080080import org.onosproject.store.service.StorageService;
81import org.onosproject.vtn.manager.VTNService;
lishuai858efd32015-12-04 14:30:36 +080082import org.onosproject.vtn.table.ArpService;
lishuai6c56f5e2015-11-17 16:38:19 +080083import org.onosproject.vtn.table.ClassifierService;
lishuai858efd32015-12-04 14:30:36 +080084import org.onosproject.vtn.table.DnatService;
lishuai6c56f5e2015-11-17 16:38:19 +080085import org.onosproject.vtn.table.L2ForwardService;
lishuai858efd32015-12-04 14:30:36 +080086import org.onosproject.vtn.table.L3ForwardService;
87import org.onosproject.vtn.table.SnatService;
lishuai74f2d532015-12-10 17:03:34 +080088import org.onosproject.vtn.table.impl.ArpServiceImpl;
lishuai6c56f5e2015-11-17 16:38:19 +080089import org.onosproject.vtn.table.impl.ClassifierServiceImpl;
lishuai74f2d532015-12-10 17:03:34 +080090import org.onosproject.vtn.table.impl.DnatServiceImpl;
lishuai6c56f5e2015-11-17 16:38:19 +080091import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
lishuai74f2d532015-12-10 17:03:34 +080092import org.onosproject.vtn.table.impl.L3ForwardServiceImpl;
93import org.onosproject.vtn.table.impl.SnatServiceImpl;
lishuai6c56f5e2015-11-17 16:38:19 +080094import org.onosproject.vtn.util.DataPathIdGenerator;
95import org.onosproject.vtn.util.VtnConfig;
96import org.onosproject.vtn.util.VtnData;
lishuai7dc63d92015-11-27 17:15:25 +080097import org.onosproject.vtnrsc.AllowedAddressPair;
98import org.onosproject.vtnrsc.BindingHostId;
99import org.onosproject.vtnrsc.DefaultVirtualPort;
100import org.onosproject.vtnrsc.FixedIp;
lishuai858efd32015-12-04 14:30:36 +0800101import org.onosproject.vtnrsc.FloatingIp;
lishuai858efd32015-12-04 14:30:36 +0800102import org.onosproject.vtnrsc.RouterInterface;
lishuai7dc63d92015-11-27 17:15:25 +0800103import org.onosproject.vtnrsc.SecurityGroup;
lishuai6c56f5e2015-11-17 16:38:19 +0800104import org.onosproject.vtnrsc.SegmentationId;
105import org.onosproject.vtnrsc.SubnetId;
106import org.onosproject.vtnrsc.TenantId;
107import org.onosproject.vtnrsc.TenantNetwork;
108import org.onosproject.vtnrsc.TenantNetworkId;
109import org.onosproject.vtnrsc.VirtualPort;
110import org.onosproject.vtnrsc.VirtualPortId;
lishuai858efd32015-12-04 14:30:36 +0800111import org.onosproject.vtnrsc.event.VtnRscEvent;
112import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
113import org.onosproject.vtnrsc.event.VtnRscListener;
114import org.onosproject.vtnrsc.floatingip.FloatingIpService;
lishuai858efd32015-12-04 14:30:36 +0800115import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
116import org.onosproject.vtnrsc.service.VtnRscService;
117import org.onosproject.vtnrsc.subnet.SubnetService;
lishuai6c56f5e2015-11-17 16:38:19 +0800118import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
119import org.onosproject.vtnrsc.virtualport.VirtualPortService;
120import org.slf4j.Logger;
121
jiangruic69a7fd2015-11-19 15:40:01 +0800122import com.google.common.collect.Lists;
lishuai6c56f5e2015-11-17 16:38:19 +0800123import com.google.common.collect.Sets;
124
125/**
126 * Provides implementation of VTNService.
127 */
128@Component(immediate = true)
129@Service
130public class VTNManager implements VTNService {
131 private final Logger log = getLogger(getClass());
132 private static final String APP_ID = "org.onosproject.app.vtn";
133
134 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
135 protected NetworkConfigService configService;
136
137 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
138 protected DeviceService deviceService;
139
140 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
141 protected HostService hostService;
142
143 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
144 protected CoreService coreService;
145
146 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
147 protected StorageService storageService;
148
149 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
150 protected TenantNetworkService tenantNetworkService;
151
152 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
153 protected VirtualPortService virtualPortService;
154
155 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
156 protected DriverService driverService;
157
158 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
159 protected LogicalClockService clockService;
160
161 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
162 protected MastershipService mastershipService;
163
jiangruic69a7fd2015-11-19 15:40:01 +0800164 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
165 protected GroupService groupService;
166
lishuai858efd32015-12-04 14:30:36 +0800167 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
168 protected SubnetService subnetService;
169
170 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
171 protected VtnRscService vtnRscService;
172
173 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
174 protected FloatingIpService floatingIpService;
175
176 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
lishuai858efd32015-12-04 14:30:36 +0800177 protected RouterInterfaceService routerInterfaceService;
178
lishuai6c56f5e2015-11-17 16:38:19 +0800179 private ApplicationId appId;
180 private ClassifierService classifierService;
181 private L2ForwardService l2ForwardService;
lishuai858efd32015-12-04 14:30:36 +0800182 private ArpService arpService;
183 private L3ForwardService l3ForwardService;
184 private SnatService snatService;
185 private DnatService dnatService;
lishuai6c56f5e2015-11-17 16:38:19 +0800186
187 private final HostListener hostListener = new InnerHostListener();
188 private final DeviceListener deviceListener = new InnerDeviceListener();
lishuai858efd32015-12-04 14:30:36 +0800189 private final VtnRscListener l3EventListener = new VtnL3EventListener();
lishuai6c56f5e2015-11-17 16:38:19 +0800190
lishuai74f2d532015-12-10 17:03:34 +0800191 private static String exPortName = "eth0";
lishuai6c56f5e2015-11-17 16:38:19 +0800192 private static final String IFACEID = "ifaceid";
193 private static final String CONTROLLER_IP_KEY = "ipaddress";
194 public static final String DRIVER_NAME = "onosfw";
lishuai7dc63d92015-11-27 17:15:25 +0800195 private static final String VIRTUALPORT = "vtn-virtual-port";
lishuai6c56f5e2015-11-17 16:38:19 +0800196 private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
197 private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
lishuai858efd32015-12-04 14:30:36 +0800198 private static final String ROUTERINF_FLAG_OF_TENANT = "routerInfFlagOfTenant";
199 private static final String HOSTS_OF_SUBNET = "hostsOfSubnet";
200 private static final String EX_PORT_OF_DEVICE = "exPortOfDevice";
jiangruic69a7fd2015-11-19 15:40:01 +0800201 private static final String DEFAULT_IP = "0.0.0.0";
lishuai858efd32015-12-04 14:30:36 +0800202 private static final int SUBNET_NUM = 2;
lishuai6c56f5e2015-11-17 16:38:19 +0800203
lishuai7dc63d92015-11-27 17:15:25 +0800204 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
lishuai6c56f5e2015-11-17 16:38:19 +0800205 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
jiangruic69a7fd2015-11-19 15:40:01 +0800206 private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
lishuai858efd32015-12-04 14:30:36 +0800207 private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet;
208 private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant;
209 private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice;
lishuai6c56f5e2015-11-17 16:38:19 +0800210
211 @Activate
212 public void activate() {
213 appId = coreService.registerApplication(APP_ID);
214 classifierService = new ClassifierServiceImpl(appId);
215 l2ForwardService = new L2ForwardServiceImpl(appId);
lishuai74f2d532015-12-10 17:03:34 +0800216 arpService = new ArpServiceImpl(appId);
217 l3ForwardService = new L3ForwardServiceImpl(appId);
218 snatService = new SnatServiceImpl(appId);
219 dnatService = new DnatServiceImpl(appId);
lishuai6c56f5e2015-11-17 16:38:19 +0800220
221 deviceService.addListener(deviceListener);
222 hostService.addListener(hostListener);
lishuai74f2d532015-12-10 17:03:34 +0800223 vtnRscService.addListener(l3EventListener);
lishuai6c56f5e2015-11-17 16:38:19 +0800224
225 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
226 .register(KryoNamespaces.API)
227 .register(NetworkOfLocalHostPorts.class)
228 .register(TenantNetworkId.class)
229 .register(Host.class)
230 .register(TenantNetwork.class)
231 .register(TenantId.class)
lishuai7dc63d92015-11-27 17:15:25 +0800232 .register(SubnetId.class)
233 .register(VirtualPortId.class)
234 .register(VirtualPort.State.class)
235 .register(AllowedAddressPair.class)
236 .register(FixedIp.class)
237 .register(BindingHostId.class)
238 .register(SecurityGroup.class)
239 .register(IpAddress.class)
240 .register(DefaultVirtualPort.class);
241
242 vPortStore = storageService
243 .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder()
244 .withName(VIRTUALPORT).withSerializer(serializer)
245 .withTimestampProvider((k, v) -> clockService.getTimestamp())
246 .build();
lishuai6c56f5e2015-11-17 16:38:19 +0800247
248 switchesOfController = storageService
249 .<IpAddress, Boolean>eventuallyConsistentMapBuilder()
250 .withName(SWITCHES_OF_CONTROLLER).withSerializer(serializer)
251 .withTimestampProvider((k, v) -> clockService.getTimestamp())
252 .build();
253
254 switchOfLocalHostPorts = storageService
jiangruic69a7fd2015-11-19 15:40:01 +0800255 .<DeviceId, NetworkOfLocalHostPorts>eventuallyConsistentMapBuilder()
256 .withName(SWITCH_OF_LOCAL_HOST_PORTS).withSerializer(serializer)
257 .withTimestampProvider((k, v) -> clockService.getTimestamp())
lishuai6c56f5e2015-11-17 16:38:19 +0800258 .build();
259
lishuai858efd32015-12-04 14:30:36 +0800260 hostsOfSubnet = storageService
261 .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder()
262 .withName(HOSTS_OF_SUBNET).withSerializer(serializer)
263 .withTimestampProvider((k, v) -> clockService.getTimestamp())
264 .build();
265
266 routerInfFlagOfTenant = storageService
267 .<TenantId, Boolean>eventuallyConsistentMapBuilder()
268 .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer)
269 .withTimestampProvider((k, v) -> clockService.getTimestamp())
270 .build();
271
272 exPortOfDevice = storageService
273 .<DeviceId, Port>eventuallyConsistentMapBuilder()
274 .withName(EX_PORT_OF_DEVICE).withSerializer(serializer)
275 .withTimestampProvider((k, v) -> clockService.getTimestamp())
276 .build();
277
lishuai6c56f5e2015-11-17 16:38:19 +0800278 log.info("Started");
279 }
280
281 @Deactivate
282 public void deactivate() {
283 deviceService.removeListener(deviceListener);
284 hostService.removeListener(hostListener);
lishuai858efd32015-12-04 14:30:36 +0800285 vtnRscService.removeListener(l3EventListener);
lishuai6c56f5e2015-11-17 16:38:19 +0800286 log.info("Stopped");
287 }
288
289 @Override
290 public void onControllerDetected(Device controllerDevice) {
291 if (controllerDevice == null) {
292 log.error("The controller device is null");
293 return;
294 }
295 String localIpAddress = controllerDevice.annotations()
296 .value(CONTROLLER_IP_KEY);
297 IpAddress localIp = IpAddress.valueOf(localIpAddress);
298 DeviceId controllerDeviceId = controllerDevice.id();
299 DriverHandler handler = driverService.createHandler(controllerDeviceId);
300 if (mastershipService.isLocalMaster(controllerDeviceId)) {
301 // Get DataPathIdGenerator
302 String ipaddress = controllerDevice.annotations().value("ipaddress");
303 DataPathIdGenerator dpidGenerator = DataPathIdGenerator.builder()
304 .addIpAddress(ipaddress).build();
305 DeviceId deviceId = dpidGenerator.getDeviceId();
306 String dpid = dpidGenerator.getDpId();
307 // Inject pipeline driver name
308 BasicDeviceConfig config = configService.addConfig(deviceId,
309 BasicDeviceConfig.class);
310 config.driver(DRIVER_NAME);
311 configService.applyConfig(deviceId, BasicDeviceConfig.class, config.node());
312 // Add Bridge
lishuai74f2d532015-12-10 17:03:34 +0800313 VtnConfig.applyBridgeConfig(handler, dpid, exPortName);
lishuai6c56f5e2015-11-17 16:38:19 +0800314 log.info("A new ovs is created in node {}", localIp.toString());
315 switchesOfController.put(localIp, true);
316 }
317 // Create tunnel in br-int on all controllers
318 programTunnelConfig(controllerDeviceId, localIp, handler);
319 }
320
321 @Override
322 public void onControllerVanished(Device controllerDevice) {
323 if (controllerDevice == null) {
324 log.error("The device is null");
325 return;
326 }
327 String dstIp = controllerDevice.annotations().value(CONTROLLER_IP_KEY);
328 IpAddress dstIpAddress = IpAddress.valueOf(dstIp);
329 DeviceId controllerDeviceId = controllerDevice.id();
330 if (mastershipService.isLocalMaster(controllerDeviceId)) {
331 switchesOfController.remove(dstIpAddress);
332 }
333 // remove tunnel in br-int on other controllers
334 programTunnelConfig(controllerDeviceId, dstIpAddress, null);
335 }
336
337 @Override
338 public void onOvsDetected(Device device) {
339 // Create tunnel out flow rules
340 applyTunnelOut(device, Objective.Operation.ADD);
341 }
342
343 @Override
344 public void onOvsVanished(Device device) {
345 // Remove Tunnel out flow rules
346 applyTunnelOut(device, Objective.Operation.REMOVE);
347 }
348
349 @Override
350 public void onHostDetected(Host host) {
lishuai858efd32015-12-04 14:30:36 +0800351 DeviceId deviceId = host.location().deviceId();
352 if (!mastershipService.isLocalMaster(deviceId)) {
353 return;
354 }
355 String ifaceId = host.annotations().value(IFACEID);
356 if (ifaceId == null) {
357 log.error("The ifaceId of Host is null");
358 return;
359 }
lishuai6c56f5e2015-11-17 16:38:19 +0800360 // apply L2 openflow rules
361 applyHostMonitoredL2Rules(host, Objective.Operation.ADD);
lishuai858efd32015-12-04 14:30:36 +0800362 // apply L3 openflow rules
363 applyHostMonitoredL3Rules(host, Objective.Operation.ADD);
lishuai6c56f5e2015-11-17 16:38:19 +0800364 }
365
366 @Override
367 public void onHostVanished(Host host) {
lishuai858efd32015-12-04 14:30:36 +0800368 DeviceId deviceId = host.location().deviceId();
369 if (!mastershipService.isLocalMaster(deviceId)) {
370 return;
371 }
372 String ifaceId = host.annotations().value(IFACEID);
373 if (ifaceId == null) {
374 log.error("The ifaceId of Host is null");
375 return;
376 }
lishuai6c56f5e2015-11-17 16:38:19 +0800377 // apply L2 openflow rules
378 applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE);
lishuai858efd32015-12-04 14:30:36 +0800379 // apply L3 openflow rules
380 applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE);
lishuai590d93a2015-12-11 13:05:14 +0800381 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
382 vPortStore.remove(virtualPortId);
lishuai6c56f5e2015-11-17 16:38:19 +0800383 }
384
385 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
386 DriverHandler localHandler) {
jiangruic69a7fd2015-11-19 15:40:01 +0800387 if (mastershipService.isLocalMaster(localDeviceId)) {
388 VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP));
389 log.info("Add tunnel on {}", localIp);
390 }
lishuai6c56f5e2015-11-17 16:38:19 +0800391 }
392
393 private void applyTunnelOut(Device device, Objective.Operation type) {
394 if (device == null) {
395 log.error("The device is null");
396 return;
397 }
398 if (!mastershipService.isLocalMaster(device.id())) {
399 return;
400 }
401 String controllerIp = VtnData.getControllerIpOfSwitch(device);
402 if (controllerIp == null) {
403 log.error("Can't find controller of device: {}",
404 device.id().toString());
405 return;
406 }
407 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
408 if (!switchesOfController.containsKey(ipAddress)) {
409 log.error("Can't find controller of device: {}",
410 device.id().toString());
411 return;
412 }
413 if (type == Objective.Operation.ADD) {
lishuaia3e32342015-12-07 10:59:17 +0800414 // Save external port
415 Port export = getExPort(device.id());
416 exPortOfDevice.put(device.id(), export);
lishuai6c56f5e2015-11-17 16:38:19 +0800417 switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts());
418 } else if (type == Objective.Operation.REMOVE) {
lishuaia3e32342015-12-07 10:59:17 +0800419 exPortOfDevice.remove(device.id());
lishuai6c56f5e2015-11-17 16:38:19 +0800420 switchOfLocalHostPorts.remove(device.id());
421 }
422 Iterable<Device> devices = deviceService.getAvailableDevices();
423 DeviceId localControllerId = VtnData.getControllerId(device, devices);
424 DriverHandler handler = driverService.createHandler(localControllerId);
425 Set<PortNumber> ports = VtnConfig.getPortNumbers(handler);
426 Iterable<Host> allHosts = hostService.getHosts();
jiangruic69a7fd2015-11-19 15:40:01 +0800427 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800428 if (allHosts != null) {
429 Sets.newHashSet(allHosts).stream().forEach(host -> {
430 MacAddress hostMac = host.mac();
431 String ifaceId = host.annotations().value(IFACEID);
432 if (ifaceId == null) {
433 log.error("The ifaceId of Host is null");
434 return;
435 }
436 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
437 VirtualPort virtualPort = virtualPortService
438 .getPort(virtualPortId);
439 TenantNetwork network = tenantNetworkService
440 .getNetwork(virtualPort.networkId());
441 SegmentationId segmentationId = network.segmentationId();
442 DeviceId remoteDeviceId = host.location().deviceId();
443 Device remoteDevice = deviceService.getDevice(remoteDeviceId);
444 String remoteControllerIp = VtnData
445 .getControllerIpOfSwitch(remoteDevice);
446 if (remoteControllerIp == null) {
447 log.error("Can't find remote controller of device: {}",
448 remoteDeviceId.toString());
449 return;
450 }
451 IpAddress remoteIpAddress = IpAddress
452 .valueOf(remoteControllerIp);
lishuai6c56f5e2015-11-17 16:38:19 +0800453 ports.stream()
454 .filter(p -> p.name().equalsIgnoreCase(tunnelName))
455 .forEach(p -> {
456 l2ForwardService
457 .programTunnelOut(device.id(), segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800458 hostMac, type, remoteIpAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800459 });
460 });
461 }
462 }
463
464 private void applyHostMonitoredL2Rules(Host host, Objective.Operation type) {
465 DeviceId deviceId = host.location().deviceId();
466 if (!mastershipService.isLocalMaster(deviceId)) {
467 return;
468 }
469 String ifaceId = host.annotations().value(IFACEID);
470 if (ifaceId == null) {
471 log.error("The ifaceId of Host is null");
472 return;
473 }
474 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
475 VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
476 if (virtualPort == null) {
lishuai858efd32015-12-04 14:30:36 +0800477 virtualPort = VtnData.getPort(vPortStore, virtualPortId);
lishuai6c56f5e2015-11-17 16:38:19 +0800478 }
lishuai74f2d532015-12-10 17:03:34 +0800479 Iterator<FixedIp> fixip = virtualPort.fixedIps().iterator();
480 SubnetId subnetId = null;
481 if (fixip.hasNext()) {
482 subnetId = fixip.next().subnetId();
483 }
484 if (subnetId != null) {
485 Map<HostId, Host> hosts = new ConcurrentHashMap();
486 if (hostsOfSubnet.get(subnetId) != null) {
487 hosts = hostsOfSubnet.get(subnetId);
488 }
489 if (type == Objective.Operation.ADD) {
490 hosts.put(host.id(), host);
491 hostsOfSubnet.put(subnetId, hosts);
492 } else if (type == Objective.Operation.REMOVE) {
493 hosts.remove(host.id());
494 if (hosts.size() != 0) {
495 hostsOfSubnet.put(subnetId, hosts);
496 } else {
497 hostsOfSubnet.remove(subnetId);
498 }
499 }
500 }
lishuai6c56f5e2015-11-17 16:38:19 +0800501
502 Iterable<Device> devices = deviceService.getAvailableDevices();
503 PortNumber inPort = host.location().port();
504 MacAddress mac = host.mac();
505 Device device = deviceService.getDevice(deviceId);
506 String controllerIp = VtnData.getControllerIpOfSwitch(device);
507 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
508 TenantNetwork network = tenantNetworkService.getNetwork(virtualPort.networkId());
509 if (network == null) {
510 log.error("Can't find network of the host");
511 return;
512 }
513 SegmentationId segmentationId = network.segmentationId();
514 // Get all the tunnel PortNumber in the current node
515 Iterable<Port> ports = deviceService.getPorts(deviceId);
516 Collection<PortNumber> localTunnelPorts = VtnData.getLocalTunnelPorts(ports);
517 // Get all the local vm's PortNumber in the current node
518 Map<TenantNetworkId, Set<PortNumber>> localHostPorts = switchOfLocalHostPorts
jiangruic69a7fd2015-11-19 15:40:01 +0800519 .get(deviceId).getNetworkOfLocalHostPorts();
lishuai6c56f5e2015-11-17 16:38:19 +0800520 Set<PortNumber> networkOflocalHostPorts = localHostPorts.get(network.id());
jiangruic69a7fd2015-11-19 15:40:01 +0800521 for (PortNumber p : localTunnelPorts) {
522 programGroupTable(deviceId, appId, p, devices, type);
523 }
lishuai6c56f5e2015-11-17 16:38:19 +0800524
525 if (type == Objective.Operation.ADD) {
lishuai7dc63d92015-11-27 17:15:25 +0800526 vPortStore.put(virtualPortId, virtualPort);
lishuai6c56f5e2015-11-17 16:38:19 +0800527 if (networkOflocalHostPorts == null) {
528 networkOflocalHostPorts = new HashSet<PortNumber>();
529 localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts);
530 }
531 networkOflocalHostPorts.add(inPort);
jiangruic69a7fd2015-11-19 15:40:01 +0800532 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
533 inPort, networkOflocalHostPorts,
534 localTunnelPorts,
535 type);
lishuai6c56f5e2015-11-17 16:38:19 +0800536 classifierService.programTunnelIn(deviceId, segmentationId,
537 localTunnelPorts,
538 type);
539 } else if (type == Objective.Operation.REMOVE) {
jiangruic69a7fd2015-11-19 15:40:01 +0800540 if (networkOflocalHostPorts != null) {
541 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
542 inPort, networkOflocalHostPorts,
543 localTunnelPorts,
544 type);
545 networkOflocalHostPorts.remove(inPort);
546 if (networkOflocalHostPorts.isEmpty()) {
547 classifierService.programTunnelIn(deviceId, segmentationId,
548 localTunnelPorts,
549 type);
550 switchOfLocalHostPorts.get(deviceId).getNetworkOfLocalHostPorts()
551 .remove(virtualPort.networkId());
552 }
lishuai6c56f5e2015-11-17 16:38:19 +0800553 }
554 }
555
jiangruic69a7fd2015-11-19 15:40:01 +0800556 l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac,
557 type);
558
lishuai6c56f5e2015-11-17 16:38:19 +0800559 l2ForwardService.programTunnelBcastRules(deviceId, segmentationId,
560 networkOflocalHostPorts,
561 localTunnelPorts,
562 type);
563
564 programTunnelOuts(devices, ipAddress, segmentationId, mac,
565 type);
566
567 classifierService.programLocalIn(deviceId, segmentationId, inPort, mac,
568 appId, type);
569 }
570
571 private void programTunnelOuts(Iterable<Device> devices,
572 IpAddress ipAddress,
573 SegmentationId segmentationId,
574 MacAddress dstMac,
575 Objective.Operation type) {
jiangruic69a7fd2015-11-19 15:40:01 +0800576 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800577 Sets.newHashSet(devices).stream()
jiangruic69a7fd2015-11-19 15:40:01 +0800578 .filter(d -> d.type() == Device.Type.CONTROLLER)
579 .filter(d -> !("ovsdb:" + ipAddress).equals(d.id().toString()))
580 .forEach(d -> {
lishuai6c56f5e2015-11-17 16:38:19 +0800581 DriverHandler handler = driverService.createHandler(d.id());
582 BridgeConfig bridgeConfig = handler
583 .behaviour(BridgeConfig.class);
584 Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
585 .getBridges();
586 Set<PortNumber> ports = bridgeConfig.getPortNumbers();
587 Iterator<BridgeDescription> it = bridgeDescriptions
588 .iterator();
589 if (it.hasNext()) {
590 BridgeDescription sw = it.next();
591 ports.stream()
592 .filter(p -> p.name()
593 .equalsIgnoreCase(tunnelName))
594 .forEach(p -> {
595 l2ForwardService.programTunnelOut(sw.deviceId(),
596 segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800597 dstMac, type, ipAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800598 });
599 }
600 });
601 }
602
603 private class InnerDeviceListener implements DeviceListener {
604
605 @Override
606 public void event(DeviceEvent event) {
607 Device device = event.subject();
608 if (Device.Type.CONTROLLER == device.type()) {
609 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
610 onControllerDetected(device);
611 }
612 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
613 if (deviceService.isAvailable(device.id())) {
614 onControllerDetected(device);
615 } else {
616 onControllerVanished(device);
617 }
618 }
619 } else if (Device.Type.SWITCH == device.type()) {
620 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
621 onOvsDetected(device);
622 }
623 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
624 if (deviceService.isAvailable(device.id())) {
625 onOvsDetected(device);
626 } else {
627 onOvsVanished(device);
628 }
629 }
630 } else {
631 log.info("Do nothing for this device type");
632 }
633 }
634 }
635
636 private class InnerHostListener implements HostListener {
637
638 @Override
639 public void event(HostEvent event) {
640 Host host = event.subject();
641 if (HostEvent.Type.HOST_ADDED == event.type()) {
642 onHostDetected(host);
643 } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
644 onHostVanished(host);
645 } else if (HostEvent.Type.HOST_UPDATED == event.type()) {
646 onHostVanished(host);
647 onHostDetected(host);
648 }
649 }
650
651 }
652
653 // Local Host Ports of Network.
654 private class NetworkOfLocalHostPorts {
655 private final Map<TenantNetworkId, Set<PortNumber>> networkOfLocalHostPorts =
656 new HashMap<TenantNetworkId, Set<PortNumber>>();
657
658 public Map<TenantNetworkId, Set<PortNumber>> getNetworkOfLocalHostPorts() {
659 return networkOfLocalHostPorts;
660 }
661 }
662
jiangruic69a7fd2015-11-19 15:40:01 +0800663 private void programGroupTable(DeviceId deviceId, ApplicationId appid,
664 PortNumber portNumber, Iterable<Device> devices, Objective.Operation type) {
665 if (type.equals(Objective.Operation.REMOVE)) {
666 return;
667 }
668
669 List<GroupBucket> buckets = Lists.newArrayList();
670 Sets.newHashSet(devices)
671 .stream()
672 .filter(d -> d.type() == Device.Type.CONTROLLER)
673 .filter(d -> !deviceId.equals(d.id()))
674 .forEach(d -> {
675 String ipAddress = d.annotations()
676 .value(CONTROLLER_IP_KEY);
677 Ip4Address dst = Ip4Address.valueOf(ipAddress);
678 Builder builder = DefaultTrafficTreatment.builder();
679
680 DriverHandler handler = driverService.createHandler(deviceId);
681 ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
682 ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
683 try {
684 treatment.setPropertyValue("tunnelDst", dst);
685 } catch (Exception e) {
686 log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
687 }
688
689 builder.extension(treatment, deviceId);
690 builder.setOutput(portNumber);
691 GroupBucket bucket = DefaultGroupBucket
692 .createAllGroupBucket(builder.build());
693 buckets.add(bucket);
694 });
695 final GroupKey key = new DefaultGroupKey(APP_ID.getBytes());
696 GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
697 GroupDescription.Type.ALL,
698 new GroupBuckets(buckets),
699 key,
700 L2ForwardServiceImpl.GROUP_ID,
701 appid);
702 groupService.addGroup(groupDescription);
703 }
lishuai858efd32015-12-04 14:30:36 +0800704
705 private class VtnL3EventListener implements VtnRscListener {
706 @Override
707 public void event(VtnRscEvent event) {
708 VtnRscEventFeedback l3Feedback = event.subject();
709 if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
710 onRouterInterfaceDetected(l3Feedback);
711 } else
712 if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
713 onRouterInterfaceVanished(l3Feedback);
714 } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) {
715 onFloatingIpDetected(l3Feedback);
716 } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) {
717 onFloatingIpVanished(l3Feedback);
718 }
719 }
720
721 }
722
723 @Override
724 public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) {
725 Objective.Operation operation = Objective.Operation.ADD;
726 RouterInterface routerInf = l3Feedback.routerInterface();
727 Iterable<RouterInterface> interfaces = routerInterfaceService
728 .getRouterInterfaces();
729 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
730 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
731 .collect(Collectors.toSet());
732 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
733 programRouterInterface(routerInf, operation);
734 } else {
735 if (interfacesSet.size() >= SUBNET_NUM) {
736 programInterfacesSet(interfacesSet, operation);
737 }
738 }
739 }
740
741 @Override
742 public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) {
743 Objective.Operation operation = Objective.Operation.REMOVE;
744 RouterInterface routerInf = l3Feedback.routerInterface();
745 Iterable<RouterInterface> interfaces = routerInterfaceService
746 .getRouterInterfaces();
747 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
748 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
749 .collect(Collectors.toSet());
750 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
751 programRouterInterface(routerInf, operation);
752 if (interfacesSet.size() == 1) {
753 routerInfFlagOfTenant.remove(routerInf.tenantId());
754 interfacesSet.stream().forEach(r -> {
755 programRouterInterface(r, operation);
756 });
757 }
758 }
759 }
760
761 @Override
762 public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
763 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT);
764 }
765
766 @Override
767 public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
768 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE);
769 }
770
771 private void programInterfacesSet(Set<RouterInterface> interfacesSet,
772 Objective.Operation operation) {
773 int subnetVmNum = 0;
774 for (RouterInterface r : interfacesSet) {
775 // Get all the host of the subnet
776 Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId());
777 if (hosts.size() > 0) {
778 subnetVmNum++;
779 if (subnetVmNum >= SUBNET_NUM) {
780 routerInfFlagOfTenant.put(r.tenantId(), true);
781 interfacesSet.stream().forEach(f -> {
782 programRouterInterface(f, operation);
783 });
784 break;
785 }
786 }
787 }
788 }
789
790 private void programRouterInterface(RouterInterface routerInf,
791 Objective.Operation operation) {
792 SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId());
793 // Get all the host of the subnet
794 Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId());
795 hosts.values().stream().forEach(h -> {
796 applyEastWestL3Flows(h, l3vni, operation);
797 });
798 }
799
800 private void applyEastWestL3Flows(Host h, SegmentationId l3vni,
801 Objective.Operation operation) {
802 if (!mastershipService.isLocalMaster(h.location().deviceId())) {
803 log.debug("not master device:{}", h.location().deviceId());
804 return;
805 }
806 String ifaceId = h.annotations().value(IFACEID);
807 VirtualPort hPort = virtualPortService
808 .getPort(VirtualPortId.portId(ifaceId));
809 if (hPort == null) {
810 hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId));
811 }
812 IpAddress srcIp = null;
813 IpAddress srcGwIp = null;
814 MacAddress srcVmGwMac = null;
815 SubnetId srcSubnetId = null;
816 Iterator<FixedIp> srcIps = hPort.fixedIps().iterator();
817 if (srcIps.hasNext()) {
818 FixedIp fixedIp = srcIps.next();
819 srcIp = fixedIp.ip();
820 srcSubnetId = fixedIp.subnetId();
821 srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp();
822 FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp);
823 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
824 if (gwPort == null) {
825 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
826 }
827 srcVmGwMac = gwPort.macAddress();
828 }
829 TenantNetwork network = tenantNetworkService
830 .getNetwork(hPort.networkId());
831 // Classifier rules
832 classifierService
833 .programL3InPortClassifierRules(h.location().deviceId(),
834 h.location().port(), h.mac(),
835 srcVmGwMac, l3vni, operation);
836 // Arp rules
837 if (operation == Objective.Operation.ADD) {
838 classifierService.programArpClassifierRules(h.location().deviceId(),
839 srcGwIp,
840 network.segmentationId(),
841 operation);
842 DriverHandler handler = driverService.createHandler(h.location().deviceId());
843 arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
844 network.segmentationId(), srcVmGwMac,
845 operation);
846 }
847 Iterable<Device> devices = deviceService.getAvailableDevices();
848 IpAddress srcArpIp = srcIp;
849 MacAddress srcArpGwMac = srcVmGwMac;
850 Sets.newHashSet(devices).stream()
851 .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> {
852 // L3FWD rules
853 l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp,
854 network.segmentationId(),
855 srcArpGwMac, h.mac(),
856 operation);
857 });
858 }
859
860 private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback,
861 VtnRscEvent.Type type) {
862 FloatingIp floaingIp = l3Feedback.floatingIp();
863 if (floaingIp != null) {
864 VirtualPortId vmPortId = floaingIp.portId();
865 VirtualPort vmPort = virtualPortService.getPort(vmPortId);
866 VirtualPort fipPort = virtualPortService
867 .getPort(floaingIp.networkId(), floaingIp.floatingIp());
868 if (vmPort == null) {
869 vmPort = VtnData.getPort(vPortStore, vmPortId);
870 }
871 if (fipPort == null) {
872 fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(),
873 floaingIp.floatingIp());
874 }
875 Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
876 Host host = null;
877 for (Host h : hostSet) {
878 String ifaceid = h.annotations().value(IFACEID);
879 if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
880 host = h;
881 break;
882 }
883 }
884 if (host != null && vmPort != null && fipPort != null) {
885 DeviceId deviceId = host.location().deviceId();
886 Port exPort = exPortOfDevice.get(deviceId);
887 SegmentationId l3vni = vtnRscService
888 .getL3vni(vmPort.tenantId());
889 // Floating ip BIND
890 if (type == VtnRscEvent.Type.FLOATINGIP_PUT) {
891 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
892 floaingIp, l3vni, exPort,
893 Objective.Operation.ADD);
894 } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) {
895 // Floating ip UNBIND
896 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
897 floaingIp, l3vni, exPort,
898 Objective.Operation.REMOVE);
899 }
900 }
901 }
902 }
903
904 private void applyNorthSouthL3Flows(DeviceId deviceId, Host host,
905 VirtualPort vmPort, VirtualPort fipPort,
906 FloatingIp floatingIp,
907 SegmentationId l3Vni, Port exPort,
908 Objective.Operation operation) {
909 if (!mastershipService.isLocalMaster(deviceId)) {
910 log.debug("not master device:{}", deviceId);
911 return;
912 }
913 List gwIpMac = getGwIpAndMac(vmPort);
914 IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
915 MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
lishuai74f2d532015-12-10 17:03:34 +0800916 List fGwIpMac = getGwIpAndMac(fipPort);
917 MacAddress fGwMac = (MacAddress) fGwIpMac.get(1);
lishuai858efd32015-12-04 14:30:36 +0800918 TenantNetwork vmNetwork = tenantNetworkService
919 .getNetwork(vmPort.networkId());
920 TenantNetwork fipNetwork = tenantNetworkService
921 .getNetwork(fipPort.networkId());
922 // L3 downlink traffic flow
lishuaia3e32342015-12-07 10:59:17 +0800923 MacAddress exPortMac = MacAddress.valueOf(exPort.annotations()
924 .value(AnnotationKeys.PORT_MAC));
lishuai858efd32015-12-04 14:30:36 +0800925 classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
926 fipNetwork.segmentationId(),
927 operation);
928 classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
929 floatingIp.floatingIp(), operation);
930 DriverHandler handler = driverService.createHandler(deviceId);
931 arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
932 fipNetwork.segmentationId(), exPortMac,
933 operation);
934 dnatService.programRules(deviceId, floatingIp.floatingIp(),
935 fGwMac, floatingIp.fixedIp(),
936 l3Vni, operation);
937 l3ForwardService
938 .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(),
939 vmNetwork.segmentationId(), dstVmGwMac,
940 vmPort.macAddress(), operation);
941
942 // L3 uplink traffic flow
943 classifierService.programL3InPortClassifierRules(deviceId,
944 host.location().port(),
945 host.mac(), dstVmGwMac,
946 l3Vni, operation);
947 snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(),
948 fGwMac, exPortMac,
949 floatingIp.floatingIp(),
950 fipNetwork.segmentationId(), operation);
951 if (operation == Objective.Operation.ADD) {
952 classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
953 vmNetwork.segmentationId(),
954 operation);
955 arpService.programArpRules(handler, deviceId, dstVmGwIp,
956 vmNetwork.segmentationId(), dstVmGwMac,
957 operation);
958 l2ForwardService.programLocalOut(deviceId,
959 fipNetwork.segmentationId(),
960 exPort.number(), fGwMac, operation);
961 }
962 }
963
964 private Port getExPort(DeviceId deviceId) {
965 List<Port> ports = deviceService.getPorts(deviceId);
966 Port exPort = null;
967 for (Port port : ports) {
968 String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
lishuai74f2d532015-12-10 17:03:34 +0800969 if (portName != null && portName.equals(exPortName)) {
lishuai858efd32015-12-04 14:30:36 +0800970 exPort = port;
971 break;
972 }
973 }
974 return exPort;
975 }
976
977 private List getGwIpAndMac(VirtualPort port) {
978 List list = new ArrayList();
979 MacAddress gwMac = null;
980 SubnetId subnetId = null;
981 IpAddress gwIp = null;
982 Iterator<FixedIp> fixips = port.fixedIps().iterator();
983 if (fixips.hasNext()) {
984 FixedIp fixip = fixips.next();
985 subnetId = fixip.subnetId();
986 gwIp = subnetService.getSubnet(subnetId).gatewayIp();
987 FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp);
988 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
989 if (gwPort == null) {
990 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
991 }
992 gwMac = gwPort.macAddress();
993 }
994 list.add(gwIp);
995 list.add(gwMac);
996 return list;
997 }
998
lishuai858efd32015-12-04 14:30:36 +0800999 private void applyHostMonitoredL3Rules(Host host,
1000 Objective.Operation operation) {
1001 String ifaceId = host.annotations().value(IFACEID);
1002 DeviceId deviceId = host.location().deviceId();
1003 VirtualPortId portId = VirtualPortId.portId(ifaceId);
1004 VirtualPort port = virtualPortService.getPort(portId);
1005 if (port == null) {
1006 port = VtnData.getPort(vPortStore, portId);
1007 }
1008 TenantId tenantId = port.tenantId();
1009 Port exPort = exPortOfDevice.get(deviceId);
1010 SegmentationId l3vni = vtnRscService.getL3vni(tenantId);
1011 Iterator<FixedIp> fixips = port.fixedIps().iterator();
1012 SubnetId sid = null;
1013 IpAddress hostIp = null;
1014 if (fixips.hasNext()) {
1015 FixedIp fixip = fixips.next();
1016 sid = fixip.subnetId();
1017 hostIp = fixip.ip();
1018 }
1019 final SubnetId subnetId = sid;
1020 // L3 internal network access to each other
1021 Iterable<RouterInterface> interfaces = routerInterfaceService
1022 .getRouterInterfaces();
1023 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
1024 .stream().filter(r -> r.tenantId().equals(tenantId))
1025 .collect(Collectors.toSet());
1026 long count = interfacesSet.stream()
1027 .filter(r -> !r.subnetId().equals(subnetId)).count();
1028 if (count > 0) {
1029 if (operation == Objective.Operation.ADD) {
1030 if (routerInfFlagOfTenant.get(tenantId) != null) {
1031 applyEastWestL3Flows(host, l3vni, operation);
1032 } else {
1033 if (interfacesSet.size() > 1) {
1034 programInterfacesSet(interfacesSet, operation);
1035 }
1036 }
1037 } else if (operation == Objective.Operation.REMOVE) {
1038 if (routerInfFlagOfTenant.get(tenantId) != null) {
1039 applyEastWestL3Flows(host, l3vni, operation);
1040 }
1041 }
1042 }
1043 // L3 external and internal network access to each other
1044 FloatingIp floatingIp = null;
1045 Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps();
1046 Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream()
1047 .filter(f -> f.tenantId().equals(tenantId))
1048 .collect(Collectors.toSet());
1049 for (FloatingIp f : floatingIpSet) {
1050 IpAddress fixedIp = f.fixedIp();
1051 if (fixedIp.equals(hostIp)) {
1052 floatingIp = f;
1053 break;
1054 }
1055 }
1056 if (floatingIp != null) {
1057 VirtualPort fipPort = virtualPortService
1058 .getPort(floatingIp.networkId(), floatingIp.floatingIp());
1059 if (fipPort == null) {
1060 fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(),
1061 floatingIp.floatingIp());
1062 }
1063 applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp,
1064 l3vni, exPort, operation);
1065 }
1066 }
lishuai74f2d532015-12-10 17:03:34 +08001067
1068 public static void setExPortName(String name) {
1069 exPortName = name;
1070 }
lishuai6c56f5e2015-11-17 16:38:19 +08001071}