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