blob: 95a320f8897ed1b2abaed4551e24c2e93c000997 [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);
lishuai6c56f5e2015-11-17 16:38:19 +0800381 }
382
383 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
384 DriverHandler localHandler) {
jiangruic69a7fd2015-11-19 15:40:01 +0800385 if (mastershipService.isLocalMaster(localDeviceId)) {
386 VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP));
387 log.info("Add tunnel on {}", localIp);
388 }
lishuai6c56f5e2015-11-17 16:38:19 +0800389 }
390
391 private void applyTunnelOut(Device device, Objective.Operation type) {
392 if (device == null) {
393 log.error("The device is null");
394 return;
395 }
396 if (!mastershipService.isLocalMaster(device.id())) {
397 return;
398 }
399 String controllerIp = VtnData.getControllerIpOfSwitch(device);
400 if (controllerIp == null) {
401 log.error("Can't find controller of device: {}",
402 device.id().toString());
403 return;
404 }
405 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
406 if (!switchesOfController.containsKey(ipAddress)) {
407 log.error("Can't find controller of device: {}",
408 device.id().toString());
409 return;
410 }
411 if (type == Objective.Operation.ADD) {
lishuaia3e32342015-12-07 10:59:17 +0800412 // Save external port
413 Port export = getExPort(device.id());
414 exPortOfDevice.put(device.id(), export);
lishuai6c56f5e2015-11-17 16:38:19 +0800415 switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts());
416 } else if (type == Objective.Operation.REMOVE) {
lishuaia3e32342015-12-07 10:59:17 +0800417 exPortOfDevice.remove(device.id());
lishuai6c56f5e2015-11-17 16:38:19 +0800418 switchOfLocalHostPorts.remove(device.id());
419 }
420 Iterable<Device> devices = deviceService.getAvailableDevices();
421 DeviceId localControllerId = VtnData.getControllerId(device, devices);
422 DriverHandler handler = driverService.createHandler(localControllerId);
423 Set<PortNumber> ports = VtnConfig.getPortNumbers(handler);
424 Iterable<Host> allHosts = hostService.getHosts();
jiangruic69a7fd2015-11-19 15:40:01 +0800425 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800426 if (allHosts != null) {
427 Sets.newHashSet(allHosts).stream().forEach(host -> {
428 MacAddress hostMac = host.mac();
429 String ifaceId = host.annotations().value(IFACEID);
430 if (ifaceId == null) {
431 log.error("The ifaceId of Host is null");
432 return;
433 }
434 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
435 VirtualPort virtualPort = virtualPortService
436 .getPort(virtualPortId);
437 TenantNetwork network = tenantNetworkService
438 .getNetwork(virtualPort.networkId());
439 SegmentationId segmentationId = network.segmentationId();
440 DeviceId remoteDeviceId = host.location().deviceId();
441 Device remoteDevice = deviceService.getDevice(remoteDeviceId);
442 String remoteControllerIp = VtnData
443 .getControllerIpOfSwitch(remoteDevice);
444 if (remoteControllerIp == null) {
445 log.error("Can't find remote controller of device: {}",
446 remoteDeviceId.toString());
447 return;
448 }
449 IpAddress remoteIpAddress = IpAddress
450 .valueOf(remoteControllerIp);
lishuai6c56f5e2015-11-17 16:38:19 +0800451 ports.stream()
452 .filter(p -> p.name().equalsIgnoreCase(tunnelName))
453 .forEach(p -> {
454 l2ForwardService
455 .programTunnelOut(device.id(), segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800456 hostMac, type, remoteIpAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800457 });
458 });
459 }
460 }
461
462 private void applyHostMonitoredL2Rules(Host host, Objective.Operation type) {
463 DeviceId deviceId = host.location().deviceId();
464 if (!mastershipService.isLocalMaster(deviceId)) {
465 return;
466 }
467 String ifaceId = host.annotations().value(IFACEID);
468 if (ifaceId == null) {
469 log.error("The ifaceId of Host is null");
470 return;
471 }
472 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
473 VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
474 if (virtualPort == null) {
lishuai858efd32015-12-04 14:30:36 +0800475 virtualPort = VtnData.getPort(vPortStore, virtualPortId);
lishuai6c56f5e2015-11-17 16:38:19 +0800476 }
lishuai74f2d532015-12-10 17:03:34 +0800477 Iterator<FixedIp> fixip = virtualPort.fixedIps().iterator();
478 SubnetId subnetId = null;
479 if (fixip.hasNext()) {
480 subnetId = fixip.next().subnetId();
481 }
482 if (subnetId != null) {
483 Map<HostId, Host> hosts = new ConcurrentHashMap();
484 if (hostsOfSubnet.get(subnetId) != null) {
485 hosts = hostsOfSubnet.get(subnetId);
486 }
487 if (type == Objective.Operation.ADD) {
488 hosts.put(host.id(), host);
489 hostsOfSubnet.put(subnetId, hosts);
490 } else if (type == Objective.Operation.REMOVE) {
491 hosts.remove(host.id());
492 if (hosts.size() != 0) {
493 hostsOfSubnet.put(subnetId, hosts);
494 } else {
495 hostsOfSubnet.remove(subnetId);
496 }
497 }
498 }
lishuai6c56f5e2015-11-17 16:38:19 +0800499
500 Iterable<Device> devices = deviceService.getAvailableDevices();
501 PortNumber inPort = host.location().port();
502 MacAddress mac = host.mac();
503 Device device = deviceService.getDevice(deviceId);
504 String controllerIp = VtnData.getControllerIpOfSwitch(device);
505 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
506 TenantNetwork network = tenantNetworkService.getNetwork(virtualPort.networkId());
507 if (network == null) {
508 log.error("Can't find network of the host");
509 return;
510 }
511 SegmentationId segmentationId = network.segmentationId();
512 // Get all the tunnel PortNumber in the current node
513 Iterable<Port> ports = deviceService.getPorts(deviceId);
514 Collection<PortNumber> localTunnelPorts = VtnData.getLocalTunnelPorts(ports);
515 // Get all the local vm's PortNumber in the current node
516 Map<TenantNetworkId, Set<PortNumber>> localHostPorts = switchOfLocalHostPorts
jiangruic69a7fd2015-11-19 15:40:01 +0800517 .get(deviceId).getNetworkOfLocalHostPorts();
lishuai6c56f5e2015-11-17 16:38:19 +0800518 Set<PortNumber> networkOflocalHostPorts = localHostPorts.get(network.id());
jiangruic69a7fd2015-11-19 15:40:01 +0800519 for (PortNumber p : localTunnelPorts) {
520 programGroupTable(deviceId, appId, p, devices, type);
521 }
lishuai6c56f5e2015-11-17 16:38:19 +0800522
523 if (type == Objective.Operation.ADD) {
lishuai7dc63d92015-11-27 17:15:25 +0800524 vPortStore.put(virtualPortId, virtualPort);
lishuai6c56f5e2015-11-17 16:38:19 +0800525 if (networkOflocalHostPorts == null) {
526 networkOflocalHostPorts = new HashSet<PortNumber>();
527 localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts);
528 }
529 networkOflocalHostPorts.add(inPort);
jiangruic69a7fd2015-11-19 15:40:01 +0800530 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
531 inPort, networkOflocalHostPorts,
532 localTunnelPorts,
533 type);
lishuai6c56f5e2015-11-17 16:38:19 +0800534 classifierService.programTunnelIn(deviceId, segmentationId,
535 localTunnelPorts,
536 type);
537 } else if (type == Objective.Operation.REMOVE) {
lishuai7dc63d92015-11-27 17:15:25 +0800538 vPortStore.remove(virtualPortId);
jiangruic69a7fd2015-11-19 15:40:01 +0800539 if (networkOflocalHostPorts != null) {
540 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
541 inPort, networkOflocalHostPorts,
542 localTunnelPorts,
543 type);
544 networkOflocalHostPorts.remove(inPort);
545 if (networkOflocalHostPorts.isEmpty()) {
546 classifierService.programTunnelIn(deviceId, segmentationId,
547 localTunnelPorts,
548 type);
549 switchOfLocalHostPorts.get(deviceId).getNetworkOfLocalHostPorts()
550 .remove(virtualPort.networkId());
551 }
lishuai6c56f5e2015-11-17 16:38:19 +0800552 }
553 }
554
jiangruic69a7fd2015-11-19 15:40:01 +0800555 l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac,
556 type);
557
lishuai6c56f5e2015-11-17 16:38:19 +0800558 l2ForwardService.programTunnelBcastRules(deviceId, segmentationId,
559 networkOflocalHostPorts,
560 localTunnelPorts,
561 type);
562
563 programTunnelOuts(devices, ipAddress, segmentationId, mac,
564 type);
565
566 classifierService.programLocalIn(deviceId, segmentationId, inPort, mac,
567 appId, type);
568 }
569
570 private void programTunnelOuts(Iterable<Device> devices,
571 IpAddress ipAddress,
572 SegmentationId segmentationId,
573 MacAddress dstMac,
574 Objective.Operation type) {
jiangruic69a7fd2015-11-19 15:40:01 +0800575 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800576 Sets.newHashSet(devices).stream()
jiangruic69a7fd2015-11-19 15:40:01 +0800577 .filter(d -> d.type() == Device.Type.CONTROLLER)
578 .filter(d -> !("ovsdb:" + ipAddress).equals(d.id().toString()))
579 .forEach(d -> {
lishuai6c56f5e2015-11-17 16:38:19 +0800580 DriverHandler handler = driverService.createHandler(d.id());
581 BridgeConfig bridgeConfig = handler
582 .behaviour(BridgeConfig.class);
583 Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
584 .getBridges();
585 Set<PortNumber> ports = bridgeConfig.getPortNumbers();
586 Iterator<BridgeDescription> it = bridgeDescriptions
587 .iterator();
588 if (it.hasNext()) {
589 BridgeDescription sw = it.next();
590 ports.stream()
591 .filter(p -> p.name()
592 .equalsIgnoreCase(tunnelName))
593 .forEach(p -> {
594 l2ForwardService.programTunnelOut(sw.deviceId(),
595 segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800596 dstMac, type, ipAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800597 });
598 }
599 });
600 }
601
602 private class InnerDeviceListener implements DeviceListener {
603
604 @Override
605 public void event(DeviceEvent event) {
606 Device device = event.subject();
607 if (Device.Type.CONTROLLER == device.type()) {
608 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
609 onControllerDetected(device);
610 }
611 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
612 if (deviceService.isAvailable(device.id())) {
613 onControllerDetected(device);
614 } else {
615 onControllerVanished(device);
616 }
617 }
618 } else if (Device.Type.SWITCH == device.type()) {
619 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
620 onOvsDetected(device);
621 }
622 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
623 if (deviceService.isAvailable(device.id())) {
624 onOvsDetected(device);
625 } else {
626 onOvsVanished(device);
627 }
628 }
629 } else {
630 log.info("Do nothing for this device type");
631 }
632 }
633 }
634
635 private class InnerHostListener implements HostListener {
636
637 @Override
638 public void event(HostEvent event) {
639 Host host = event.subject();
640 if (HostEvent.Type.HOST_ADDED == event.type()) {
641 onHostDetected(host);
642 } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
643 onHostVanished(host);
644 } else if (HostEvent.Type.HOST_UPDATED == event.type()) {
645 onHostVanished(host);
646 onHostDetected(host);
647 }
648 }
649
650 }
651
652 // Local Host Ports of Network.
653 private class NetworkOfLocalHostPorts {
654 private final Map<TenantNetworkId, Set<PortNumber>> networkOfLocalHostPorts =
655 new HashMap<TenantNetworkId, Set<PortNumber>>();
656
657 public Map<TenantNetworkId, Set<PortNumber>> getNetworkOfLocalHostPorts() {
658 return networkOfLocalHostPorts;
659 }
660 }
661
jiangruic69a7fd2015-11-19 15:40:01 +0800662 private void programGroupTable(DeviceId deviceId, ApplicationId appid,
663 PortNumber portNumber, Iterable<Device> devices, Objective.Operation type) {
664 if (type.equals(Objective.Operation.REMOVE)) {
665 return;
666 }
667
668 List<GroupBucket> buckets = Lists.newArrayList();
669 Sets.newHashSet(devices)
670 .stream()
671 .filter(d -> d.type() == Device.Type.CONTROLLER)
672 .filter(d -> !deviceId.equals(d.id()))
673 .forEach(d -> {
674 String ipAddress = d.annotations()
675 .value(CONTROLLER_IP_KEY);
676 Ip4Address dst = Ip4Address.valueOf(ipAddress);
677 Builder builder = DefaultTrafficTreatment.builder();
678
679 DriverHandler handler = driverService.createHandler(deviceId);
680 ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
681 ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
682 try {
683 treatment.setPropertyValue("tunnelDst", dst);
684 } catch (Exception e) {
685 log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
686 }
687
688 builder.extension(treatment, deviceId);
689 builder.setOutput(portNumber);
690 GroupBucket bucket = DefaultGroupBucket
691 .createAllGroupBucket(builder.build());
692 buckets.add(bucket);
693 });
694 final GroupKey key = new DefaultGroupKey(APP_ID.getBytes());
695 GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
696 GroupDescription.Type.ALL,
697 new GroupBuckets(buckets),
698 key,
699 L2ForwardServiceImpl.GROUP_ID,
700 appid);
701 groupService.addGroup(groupDescription);
702 }
lishuai858efd32015-12-04 14:30:36 +0800703
704 private class VtnL3EventListener implements VtnRscListener {
705 @Override
706 public void event(VtnRscEvent event) {
707 VtnRscEventFeedback l3Feedback = event.subject();
708 if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
709 onRouterInterfaceDetected(l3Feedback);
710 } else
711 if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
712 onRouterInterfaceVanished(l3Feedback);
713 } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) {
714 onFloatingIpDetected(l3Feedback);
715 } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) {
716 onFloatingIpVanished(l3Feedback);
717 }
718 }
719
720 }
721
722 @Override
723 public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) {
724 Objective.Operation operation = Objective.Operation.ADD;
725 RouterInterface routerInf = l3Feedback.routerInterface();
726 Iterable<RouterInterface> interfaces = routerInterfaceService
727 .getRouterInterfaces();
728 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
729 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
730 .collect(Collectors.toSet());
731 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
732 programRouterInterface(routerInf, operation);
733 } else {
734 if (interfacesSet.size() >= SUBNET_NUM) {
735 programInterfacesSet(interfacesSet, operation);
736 }
737 }
738 }
739
740 @Override
741 public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) {
742 Objective.Operation operation = Objective.Operation.REMOVE;
743 RouterInterface routerInf = l3Feedback.routerInterface();
744 Iterable<RouterInterface> interfaces = routerInterfaceService
745 .getRouterInterfaces();
746 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
747 .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
748 .collect(Collectors.toSet());
749 if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
750 programRouterInterface(routerInf, operation);
751 if (interfacesSet.size() == 1) {
752 routerInfFlagOfTenant.remove(routerInf.tenantId());
753 interfacesSet.stream().forEach(r -> {
754 programRouterInterface(r, operation);
755 });
756 }
757 }
758 }
759
760 @Override
761 public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
762 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT);
763 }
764
765 @Override
766 public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
767 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE);
768 }
769
770 private void programInterfacesSet(Set<RouterInterface> interfacesSet,
771 Objective.Operation operation) {
772 int subnetVmNum = 0;
773 for (RouterInterface r : interfacesSet) {
774 // Get all the host of the subnet
775 Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId());
776 if (hosts.size() > 0) {
777 subnetVmNum++;
778 if (subnetVmNum >= SUBNET_NUM) {
779 routerInfFlagOfTenant.put(r.tenantId(), true);
780 interfacesSet.stream().forEach(f -> {
781 programRouterInterface(f, operation);
782 });
783 break;
784 }
785 }
786 }
787 }
788
789 private void programRouterInterface(RouterInterface routerInf,
790 Objective.Operation operation) {
791 SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId());
792 // Get all the host of the subnet
793 Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId());
794 hosts.values().stream().forEach(h -> {
795 applyEastWestL3Flows(h, l3vni, operation);
796 });
797 }
798
799 private void applyEastWestL3Flows(Host h, SegmentationId l3vni,
800 Objective.Operation operation) {
801 if (!mastershipService.isLocalMaster(h.location().deviceId())) {
802 log.debug("not master device:{}", h.location().deviceId());
803 return;
804 }
805 String ifaceId = h.annotations().value(IFACEID);
806 VirtualPort hPort = virtualPortService
807 .getPort(VirtualPortId.portId(ifaceId));
808 if (hPort == null) {
809 hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId));
810 }
811 IpAddress srcIp = null;
812 IpAddress srcGwIp = null;
813 MacAddress srcVmGwMac = null;
814 SubnetId srcSubnetId = null;
815 Iterator<FixedIp> srcIps = hPort.fixedIps().iterator();
816 if (srcIps.hasNext()) {
817 FixedIp fixedIp = srcIps.next();
818 srcIp = fixedIp.ip();
819 srcSubnetId = fixedIp.subnetId();
820 srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp();
821 FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp);
822 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
823 if (gwPort == null) {
824 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
825 }
826 srcVmGwMac = gwPort.macAddress();
827 }
828 TenantNetwork network = tenantNetworkService
829 .getNetwork(hPort.networkId());
830 // Classifier rules
831 classifierService
832 .programL3InPortClassifierRules(h.location().deviceId(),
833 h.location().port(), h.mac(),
834 srcVmGwMac, l3vni, operation);
835 // Arp rules
836 if (operation == Objective.Operation.ADD) {
837 classifierService.programArpClassifierRules(h.location().deviceId(),
838 srcGwIp,
839 network.segmentationId(),
840 operation);
841 DriverHandler handler = driverService.createHandler(h.location().deviceId());
842 arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
843 network.segmentationId(), srcVmGwMac,
844 operation);
845 }
846 Iterable<Device> devices = deviceService.getAvailableDevices();
847 IpAddress srcArpIp = srcIp;
848 MacAddress srcArpGwMac = srcVmGwMac;
849 Sets.newHashSet(devices).stream()
850 .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> {
851 // L3FWD rules
852 l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp,
853 network.segmentationId(),
854 srcArpGwMac, h.mac(),
855 operation);
856 });
857 }
858
859 private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback,
860 VtnRscEvent.Type type) {
861 FloatingIp floaingIp = l3Feedback.floatingIp();
862 if (floaingIp != null) {
863 VirtualPortId vmPortId = floaingIp.portId();
864 VirtualPort vmPort = virtualPortService.getPort(vmPortId);
865 VirtualPort fipPort = virtualPortService
866 .getPort(floaingIp.networkId(), floaingIp.floatingIp());
867 if (vmPort == null) {
868 vmPort = VtnData.getPort(vPortStore, vmPortId);
869 }
870 if (fipPort == null) {
871 fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(),
872 floaingIp.floatingIp());
873 }
874 Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
875 Host host = null;
876 for (Host h : hostSet) {
877 String ifaceid = h.annotations().value(IFACEID);
878 if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
879 host = h;
880 break;
881 }
882 }
883 if (host != null && vmPort != null && fipPort != null) {
884 DeviceId deviceId = host.location().deviceId();
885 Port exPort = exPortOfDevice.get(deviceId);
886 SegmentationId l3vni = vtnRscService
887 .getL3vni(vmPort.tenantId());
888 // Floating ip BIND
889 if (type == VtnRscEvent.Type.FLOATINGIP_PUT) {
890 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
891 floaingIp, l3vni, exPort,
892 Objective.Operation.ADD);
893 } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) {
894 // Floating ip UNBIND
895 applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
896 floaingIp, l3vni, exPort,
897 Objective.Operation.REMOVE);
898 }
899 }
900 }
901 }
902
903 private void applyNorthSouthL3Flows(DeviceId deviceId, Host host,
904 VirtualPort vmPort, VirtualPort fipPort,
905 FloatingIp floatingIp,
906 SegmentationId l3Vni, Port exPort,
907 Objective.Operation operation) {
908 if (!mastershipService.isLocalMaster(deviceId)) {
909 log.debug("not master device:{}", deviceId);
910 return;
911 }
912 List gwIpMac = getGwIpAndMac(vmPort);
913 IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
914 MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
lishuai74f2d532015-12-10 17:03:34 +0800915 List fGwIpMac = getGwIpAndMac(fipPort);
916 MacAddress fGwMac = (MacAddress) fGwIpMac.get(1);
lishuai858efd32015-12-04 14:30:36 +0800917 TenantNetwork vmNetwork = tenantNetworkService
918 .getNetwork(vmPort.networkId());
919 TenantNetwork fipNetwork = tenantNetworkService
920 .getNetwork(fipPort.networkId());
921 // L3 downlink traffic flow
lishuaia3e32342015-12-07 10:59:17 +0800922 MacAddress exPortMac = MacAddress.valueOf(exPort.annotations()
923 .value(AnnotationKeys.PORT_MAC));
lishuai858efd32015-12-04 14:30:36 +0800924 classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
925 fipNetwork.segmentationId(),
926 operation);
927 classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
928 floatingIp.floatingIp(), operation);
929 DriverHandler handler = driverService.createHandler(deviceId);
930 arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
931 fipNetwork.segmentationId(), exPortMac,
932 operation);
933 dnatService.programRules(deviceId, floatingIp.floatingIp(),
934 fGwMac, floatingIp.fixedIp(),
935 l3Vni, operation);
936 l3ForwardService
937 .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(),
938 vmNetwork.segmentationId(), dstVmGwMac,
939 vmPort.macAddress(), operation);
940
941 // L3 uplink traffic flow
942 classifierService.programL3InPortClassifierRules(deviceId,
943 host.location().port(),
944 host.mac(), dstVmGwMac,
945 l3Vni, operation);
946 snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(),
947 fGwMac, exPortMac,
948 floatingIp.floatingIp(),
949 fipNetwork.segmentationId(), operation);
950 if (operation == Objective.Operation.ADD) {
951 classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
952 vmNetwork.segmentationId(),
953 operation);
954 arpService.programArpRules(handler, deviceId, dstVmGwIp,
955 vmNetwork.segmentationId(), dstVmGwMac,
956 operation);
957 l2ForwardService.programLocalOut(deviceId,
958 fipNetwork.segmentationId(),
959 exPort.number(), fGwMac, operation);
960 }
961 }
962
963 private Port getExPort(DeviceId deviceId) {
964 List<Port> ports = deviceService.getPorts(deviceId);
965 Port exPort = null;
966 for (Port port : ports) {
967 String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
lishuai74f2d532015-12-10 17:03:34 +0800968 if (portName != null && portName.equals(exPortName)) {
lishuai858efd32015-12-04 14:30:36 +0800969 exPort = port;
970 break;
971 }
972 }
973 return exPort;
974 }
975
976 private List getGwIpAndMac(VirtualPort port) {
977 List list = new ArrayList();
978 MacAddress gwMac = null;
979 SubnetId subnetId = null;
980 IpAddress gwIp = null;
981 Iterator<FixedIp> fixips = port.fixedIps().iterator();
982 if (fixips.hasNext()) {
983 FixedIp fixip = fixips.next();
984 subnetId = fixip.subnetId();
985 gwIp = subnetService.getSubnet(subnetId).gatewayIp();
986 FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp);
987 VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
988 if (gwPort == null) {
989 gwPort = VtnData.getPort(vPortStore, fixedGwIp);
990 }
991 gwMac = gwPort.macAddress();
992 }
993 list.add(gwIp);
994 list.add(gwMac);
995 return list;
996 }
997
lishuai858efd32015-12-04 14:30:36 +0800998 private void applyHostMonitoredL3Rules(Host host,
999 Objective.Operation operation) {
1000 String ifaceId = host.annotations().value(IFACEID);
1001 DeviceId deviceId = host.location().deviceId();
1002 VirtualPortId portId = VirtualPortId.portId(ifaceId);
1003 VirtualPort port = virtualPortService.getPort(portId);
1004 if (port == null) {
1005 port = VtnData.getPort(vPortStore, portId);
1006 }
1007 TenantId tenantId = port.tenantId();
1008 Port exPort = exPortOfDevice.get(deviceId);
1009 SegmentationId l3vni = vtnRscService.getL3vni(tenantId);
1010 Iterator<FixedIp> fixips = port.fixedIps().iterator();
1011 SubnetId sid = null;
1012 IpAddress hostIp = null;
1013 if (fixips.hasNext()) {
1014 FixedIp fixip = fixips.next();
1015 sid = fixip.subnetId();
1016 hostIp = fixip.ip();
1017 }
1018 final SubnetId subnetId = sid;
1019 // L3 internal network access to each other
1020 Iterable<RouterInterface> interfaces = routerInterfaceService
1021 .getRouterInterfaces();
1022 Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
1023 .stream().filter(r -> r.tenantId().equals(tenantId))
1024 .collect(Collectors.toSet());
1025 long count = interfacesSet.stream()
1026 .filter(r -> !r.subnetId().equals(subnetId)).count();
1027 if (count > 0) {
1028 if (operation == Objective.Operation.ADD) {
1029 if (routerInfFlagOfTenant.get(tenantId) != null) {
1030 applyEastWestL3Flows(host, l3vni, operation);
1031 } else {
1032 if (interfacesSet.size() > 1) {
1033 programInterfacesSet(interfacesSet, operation);
1034 }
1035 }
1036 } else if (operation == Objective.Operation.REMOVE) {
1037 if (routerInfFlagOfTenant.get(tenantId) != null) {
1038 applyEastWestL3Flows(host, l3vni, operation);
1039 }
1040 }
1041 }
1042 // L3 external and internal network access to each other
1043 FloatingIp floatingIp = null;
1044 Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps();
1045 Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream()
1046 .filter(f -> f.tenantId().equals(tenantId))
1047 .collect(Collectors.toSet());
1048 for (FloatingIp f : floatingIpSet) {
1049 IpAddress fixedIp = f.fixedIp();
1050 if (fixedIp.equals(hostIp)) {
1051 floatingIp = f;
1052 break;
1053 }
1054 }
1055 if (floatingIp != null) {
1056 VirtualPort fipPort = virtualPortService
1057 .getPort(floatingIp.networkId(), floatingIp.floatingIp());
1058 if (fipPort == null) {
1059 fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(),
1060 floatingIp.floatingIp());
1061 }
1062 applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp,
1063 l3vni, exPort, operation);
1064 }
1065 }
lishuai74f2d532015-12-10 17:03:34 +08001066
1067 public static void setExPortName(String name) {
1068 exPortName = name;
1069 }
lishuai6c56f5e2015-11-17 16:38:19 +08001070}