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