blob: be6b936449cc9c58fe88fcd7734a5b20b84729f6 [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
21import java.util.Collection;
22import java.util.HashMap;
23import java.util.HashSet;
24import java.util.Iterator;
jiangruic69a7fd2015-11-19 15:40:01 +080025import java.util.List;
lishuai6c56f5e2015-11-17 16:38:19 +080026import java.util.Map;
27import java.util.Set;
28
29import org.apache.felix.scr.annotations.Activate;
30import org.apache.felix.scr.annotations.Component;
31import org.apache.felix.scr.annotations.Deactivate;
32import org.apache.felix.scr.annotations.Reference;
33import org.apache.felix.scr.annotations.ReferenceCardinality;
34import org.apache.felix.scr.annotations.Service;
jiangruic69a7fd2015-11-19 15:40:01 +080035import org.onlab.packet.Ip4Address;
lishuai6c56f5e2015-11-17 16:38:19 +080036import org.onlab.packet.IpAddress;
37import org.onlab.packet.MacAddress;
38import org.onlab.util.KryoNamespace;
39import org.onosproject.core.ApplicationId;
40import org.onosproject.core.CoreService;
41import org.onosproject.mastership.MastershipService;
42import org.onosproject.net.Device;
43import org.onosproject.net.DeviceId;
44import org.onosproject.net.Host;
45import org.onosproject.net.Port;
46import org.onosproject.net.PortNumber;
47import org.onosproject.net.behaviour.BridgeConfig;
48import org.onosproject.net.behaviour.BridgeDescription;
jiangruic69a7fd2015-11-19 15:40:01 +080049import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
lishuai6c56f5e2015-11-17 16:38:19 +080050import org.onosproject.net.config.NetworkConfigService;
51import org.onosproject.net.config.basics.BasicDeviceConfig;
52import org.onosproject.net.device.DeviceEvent;
53import org.onosproject.net.device.DeviceListener;
54import org.onosproject.net.device.DeviceService;
55import org.onosproject.net.driver.DriverHandler;
56import org.onosproject.net.driver.DriverService;
jiangruic69a7fd2015-11-19 15:40:01 +080057import org.onosproject.net.flow.DefaultTrafficTreatment;
58import org.onosproject.net.flow.TrafficTreatment.Builder;
59import org.onosproject.net.flow.instructions.ExtensionTreatment;
lishuai6c56f5e2015-11-17 16:38:19 +080060import org.onosproject.net.flowobjective.Objective;
jiangruic69a7fd2015-11-19 15:40:01 +080061import org.onosproject.net.group.DefaultGroupBucket;
62import org.onosproject.net.group.DefaultGroupDescription;
63import org.onosproject.net.group.DefaultGroupKey;
64import org.onosproject.net.group.GroupBucket;
65import org.onosproject.net.group.GroupBuckets;
66import org.onosproject.net.group.GroupDescription;
67import org.onosproject.net.group.GroupKey;
68import org.onosproject.net.group.GroupService;
lishuai6c56f5e2015-11-17 16:38:19 +080069import org.onosproject.net.host.HostEvent;
70import org.onosproject.net.host.HostListener;
71import org.onosproject.net.host.HostService;
72import org.onosproject.store.serializers.KryoNamespaces;
lishuai6c56f5e2015-11-17 16:38:19 +080073import org.onosproject.store.service.EventuallyConsistentMap;
74import org.onosproject.store.service.LogicalClockService;
lishuai6c56f5e2015-11-17 16:38:19 +080075import org.onosproject.store.service.StorageService;
76import org.onosproject.vtn.manager.VTNService;
77import org.onosproject.vtn.table.ClassifierService;
78import org.onosproject.vtn.table.L2ForwardService;
79import org.onosproject.vtn.table.impl.ClassifierServiceImpl;
80import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
81import org.onosproject.vtn.util.DataPathIdGenerator;
82import org.onosproject.vtn.util.VtnConfig;
83import org.onosproject.vtn.util.VtnData;
lishuai7dc63d92015-11-27 17:15:25 +080084import org.onosproject.vtnrsc.AllowedAddressPair;
85import org.onosproject.vtnrsc.BindingHostId;
86import org.onosproject.vtnrsc.DefaultVirtualPort;
87import org.onosproject.vtnrsc.FixedIp;
88import org.onosproject.vtnrsc.SecurityGroup;
lishuai6c56f5e2015-11-17 16:38:19 +080089import org.onosproject.vtnrsc.SegmentationId;
90import org.onosproject.vtnrsc.SubnetId;
91import org.onosproject.vtnrsc.TenantId;
92import org.onosproject.vtnrsc.TenantNetwork;
93import org.onosproject.vtnrsc.TenantNetworkId;
94import org.onosproject.vtnrsc.VirtualPort;
95import org.onosproject.vtnrsc.VirtualPortId;
96import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
97import org.onosproject.vtnrsc.virtualport.VirtualPortService;
98import org.slf4j.Logger;
99
jiangruic69a7fd2015-11-19 15:40:01 +0800100import com.google.common.collect.Lists;
lishuai6c56f5e2015-11-17 16:38:19 +0800101import com.google.common.collect.Sets;
102
103/**
104 * Provides implementation of VTNService.
105 */
106@Component(immediate = true)
107@Service
108public class VTNManager implements VTNService {
109 private final Logger log = getLogger(getClass());
110 private static final String APP_ID = "org.onosproject.app.vtn";
111
112 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
113 protected NetworkConfigService configService;
114
115 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
116 protected DeviceService deviceService;
117
118 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
119 protected HostService hostService;
120
121 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
122 protected CoreService coreService;
123
124 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
125 protected StorageService storageService;
126
127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
128 protected TenantNetworkService tenantNetworkService;
129
130 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
131 protected VirtualPortService virtualPortService;
132
133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
134 protected DriverService driverService;
135
136 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
137 protected LogicalClockService clockService;
138
139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
140 protected MastershipService mastershipService;
141
jiangruic69a7fd2015-11-19 15:40:01 +0800142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
143 protected GroupService groupService;
144
lishuai6c56f5e2015-11-17 16:38:19 +0800145 private ApplicationId appId;
146 private ClassifierService classifierService;
147 private L2ForwardService l2ForwardService;
148
149 private final HostListener hostListener = new InnerHostListener();
150 private final DeviceListener deviceListener = new InnerDeviceListener();
151
152 private static final String IFACEID = "ifaceid";
153 private static final String CONTROLLER_IP_KEY = "ipaddress";
154 public static final String DRIVER_NAME = "onosfw";
155 private static final String EX_PORT_NAME = "eth0";
lishuai7dc63d92015-11-27 17:15:25 +0800156 private static final String VIRTUALPORT = "vtn-virtual-port";
lishuai6c56f5e2015-11-17 16:38:19 +0800157 private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
158 private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
jiangruic69a7fd2015-11-19 15:40:01 +0800159 private static final String DEFAULT_IP = "0.0.0.0";
lishuai6c56f5e2015-11-17 16:38:19 +0800160
lishuai7dc63d92015-11-27 17:15:25 +0800161 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
lishuai6c56f5e2015-11-17 16:38:19 +0800162 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
jiangruic69a7fd2015-11-19 15:40:01 +0800163 private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
lishuai6c56f5e2015-11-17 16:38:19 +0800164
165 @Activate
166 public void activate() {
167 appId = coreService.registerApplication(APP_ID);
168 classifierService = new ClassifierServiceImpl(appId);
169 l2ForwardService = new L2ForwardServiceImpl(appId);
170
171 deviceService.addListener(deviceListener);
172 hostService.addListener(hostListener);
173
174 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
175 .register(KryoNamespaces.API)
176 .register(NetworkOfLocalHostPorts.class)
177 .register(TenantNetworkId.class)
178 .register(Host.class)
179 .register(TenantNetwork.class)
180 .register(TenantId.class)
lishuai7dc63d92015-11-27 17:15:25 +0800181 .register(SubnetId.class)
182 .register(VirtualPortId.class)
183 .register(VirtualPort.State.class)
184 .register(AllowedAddressPair.class)
185 .register(FixedIp.class)
186 .register(BindingHostId.class)
187 .register(SecurityGroup.class)
188 .register(IpAddress.class)
189 .register(DefaultVirtualPort.class);
190
191 vPortStore = storageService
192 .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder()
193 .withName(VIRTUALPORT).withSerializer(serializer)
194 .withTimestampProvider((k, v) -> clockService.getTimestamp())
195 .build();
lishuai6c56f5e2015-11-17 16:38:19 +0800196
197 switchesOfController = storageService
198 .<IpAddress, Boolean>eventuallyConsistentMapBuilder()
199 .withName(SWITCHES_OF_CONTROLLER).withSerializer(serializer)
200 .withTimestampProvider((k, v) -> clockService.getTimestamp())
201 .build();
202
203 switchOfLocalHostPorts = storageService
jiangruic69a7fd2015-11-19 15:40:01 +0800204 .<DeviceId, NetworkOfLocalHostPorts>eventuallyConsistentMapBuilder()
205 .withName(SWITCH_OF_LOCAL_HOST_PORTS).withSerializer(serializer)
206 .withTimestampProvider((k, v) -> clockService.getTimestamp())
lishuai6c56f5e2015-11-17 16:38:19 +0800207 .build();
208
209 log.info("Started");
210 }
211
212 @Deactivate
213 public void deactivate() {
214 deviceService.removeListener(deviceListener);
215 hostService.removeListener(hostListener);
216 log.info("Stopped");
217 }
218
219 @Override
220 public void onControllerDetected(Device controllerDevice) {
221 if (controllerDevice == null) {
222 log.error("The controller device is null");
223 return;
224 }
225 String localIpAddress = controllerDevice.annotations()
226 .value(CONTROLLER_IP_KEY);
227 IpAddress localIp = IpAddress.valueOf(localIpAddress);
228 DeviceId controllerDeviceId = controllerDevice.id();
229 DriverHandler handler = driverService.createHandler(controllerDeviceId);
230 if (mastershipService.isLocalMaster(controllerDeviceId)) {
231 // Get DataPathIdGenerator
232 String ipaddress = controllerDevice.annotations().value("ipaddress");
233 DataPathIdGenerator dpidGenerator = DataPathIdGenerator.builder()
234 .addIpAddress(ipaddress).build();
235 DeviceId deviceId = dpidGenerator.getDeviceId();
236 String dpid = dpidGenerator.getDpId();
237 // Inject pipeline driver name
238 BasicDeviceConfig config = configService.addConfig(deviceId,
239 BasicDeviceConfig.class);
240 config.driver(DRIVER_NAME);
241 configService.applyConfig(deviceId, BasicDeviceConfig.class, config.node());
242 // Add Bridge
243 VtnConfig.applyBridgeConfig(handler, dpid, EX_PORT_NAME);
244 log.info("A new ovs is created in node {}", localIp.toString());
245 switchesOfController.put(localIp, true);
246 }
247 // Create tunnel in br-int on all controllers
248 programTunnelConfig(controllerDeviceId, localIp, handler);
249 }
250
251 @Override
252 public void onControllerVanished(Device controllerDevice) {
253 if (controllerDevice == null) {
254 log.error("The device is null");
255 return;
256 }
257 String dstIp = controllerDevice.annotations().value(CONTROLLER_IP_KEY);
258 IpAddress dstIpAddress = IpAddress.valueOf(dstIp);
259 DeviceId controllerDeviceId = controllerDevice.id();
260 if (mastershipService.isLocalMaster(controllerDeviceId)) {
261 switchesOfController.remove(dstIpAddress);
262 }
263 // remove tunnel in br-int on other controllers
264 programTunnelConfig(controllerDeviceId, dstIpAddress, null);
265 }
266
267 @Override
268 public void onOvsDetected(Device device) {
269 // Create tunnel out flow rules
270 applyTunnelOut(device, Objective.Operation.ADD);
271 }
272
273 @Override
274 public void onOvsVanished(Device device) {
275 // Remove Tunnel out flow rules
276 applyTunnelOut(device, Objective.Operation.REMOVE);
277 }
278
279 @Override
280 public void onHostDetected(Host host) {
281 // apply L2 openflow rules
282 applyHostMonitoredL2Rules(host, Objective.Operation.ADD);
283 }
284
285 @Override
286 public void onHostVanished(Host host) {
287 // apply L2 openflow rules
288 applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE);
289 }
290
291 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
292 DriverHandler localHandler) {
jiangruic69a7fd2015-11-19 15:40:01 +0800293 if (mastershipService.isLocalMaster(localDeviceId)) {
294 VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP));
295 log.info("Add tunnel on {}", localIp);
296 }
lishuai6c56f5e2015-11-17 16:38:19 +0800297 }
298
299 private void applyTunnelOut(Device device, Objective.Operation type) {
300 if (device == null) {
301 log.error("The device is null");
302 return;
303 }
304 if (!mastershipService.isLocalMaster(device.id())) {
305 return;
306 }
307 String controllerIp = VtnData.getControllerIpOfSwitch(device);
308 if (controllerIp == null) {
309 log.error("Can't find controller of device: {}",
310 device.id().toString());
311 return;
312 }
313 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
314 if (!switchesOfController.containsKey(ipAddress)) {
315 log.error("Can't find controller of device: {}",
316 device.id().toString());
317 return;
318 }
319 if (type == Objective.Operation.ADD) {
320 switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts());
321 } else if (type == Objective.Operation.REMOVE) {
322 switchOfLocalHostPorts.remove(device.id());
323 }
324 Iterable<Device> devices = deviceService.getAvailableDevices();
325 DeviceId localControllerId = VtnData.getControllerId(device, devices);
326 DriverHandler handler = driverService.createHandler(localControllerId);
327 Set<PortNumber> ports = VtnConfig.getPortNumbers(handler);
328 Iterable<Host> allHosts = hostService.getHosts();
jiangruic69a7fd2015-11-19 15:40:01 +0800329 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800330 if (allHosts != null) {
331 Sets.newHashSet(allHosts).stream().forEach(host -> {
332 MacAddress hostMac = host.mac();
333 String ifaceId = host.annotations().value(IFACEID);
334 if (ifaceId == null) {
335 log.error("The ifaceId of Host is null");
336 return;
337 }
338 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
339 VirtualPort virtualPort = virtualPortService
340 .getPort(virtualPortId);
341 TenantNetwork network = tenantNetworkService
342 .getNetwork(virtualPort.networkId());
343 SegmentationId segmentationId = network.segmentationId();
344 DeviceId remoteDeviceId = host.location().deviceId();
345 Device remoteDevice = deviceService.getDevice(remoteDeviceId);
346 String remoteControllerIp = VtnData
347 .getControllerIpOfSwitch(remoteDevice);
348 if (remoteControllerIp == null) {
349 log.error("Can't find remote controller of device: {}",
350 remoteDeviceId.toString());
351 return;
352 }
353 IpAddress remoteIpAddress = IpAddress
354 .valueOf(remoteControllerIp);
lishuai6c56f5e2015-11-17 16:38:19 +0800355 ports.stream()
356 .filter(p -> p.name().equalsIgnoreCase(tunnelName))
357 .forEach(p -> {
358 l2ForwardService
359 .programTunnelOut(device.id(), segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800360 hostMac, type, remoteIpAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800361 });
362 });
363 }
364 }
365
366 private void applyHostMonitoredL2Rules(Host host, Objective.Operation type) {
367 DeviceId deviceId = host.location().deviceId();
368 if (!mastershipService.isLocalMaster(deviceId)) {
369 return;
370 }
371 String ifaceId = host.annotations().value(IFACEID);
372 if (ifaceId == null) {
373 log.error("The ifaceId of Host is null");
374 return;
375 }
376 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
377 VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
378 if (virtualPort == null) {
lishuai7dc63d92015-11-27 17:15:25 +0800379 virtualPort = vPortStore.get(virtualPortId);
lishuai6c56f5e2015-11-17 16:38:19 +0800380 }
381
382 Iterable<Device> devices = deviceService.getAvailableDevices();
383 PortNumber inPort = host.location().port();
384 MacAddress mac = host.mac();
385 Device device = deviceService.getDevice(deviceId);
386 String controllerIp = VtnData.getControllerIpOfSwitch(device);
387 IpAddress ipAddress = IpAddress.valueOf(controllerIp);
388 TenantNetwork network = tenantNetworkService.getNetwork(virtualPort.networkId());
389 if (network == null) {
390 log.error("Can't find network of the host");
391 return;
392 }
393 SegmentationId segmentationId = network.segmentationId();
394 // Get all the tunnel PortNumber in the current node
395 Iterable<Port> ports = deviceService.getPorts(deviceId);
396 Collection<PortNumber> localTunnelPorts = VtnData.getLocalTunnelPorts(ports);
397 // Get all the local vm's PortNumber in the current node
398 Map<TenantNetworkId, Set<PortNumber>> localHostPorts = switchOfLocalHostPorts
jiangruic69a7fd2015-11-19 15:40:01 +0800399 .get(deviceId).getNetworkOfLocalHostPorts();
lishuai6c56f5e2015-11-17 16:38:19 +0800400 Set<PortNumber> networkOflocalHostPorts = localHostPorts.get(network.id());
jiangruic69a7fd2015-11-19 15:40:01 +0800401 for (PortNumber p : localTunnelPorts) {
402 programGroupTable(deviceId, appId, p, devices, type);
403 }
lishuai6c56f5e2015-11-17 16:38:19 +0800404
405 if (type == Objective.Operation.ADD) {
lishuai7dc63d92015-11-27 17:15:25 +0800406 vPortStore.put(virtualPortId, virtualPort);
lishuai6c56f5e2015-11-17 16:38:19 +0800407 if (networkOflocalHostPorts == null) {
408 networkOflocalHostPorts = new HashSet<PortNumber>();
409 localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts);
410 }
411 networkOflocalHostPorts.add(inPort);
jiangruic69a7fd2015-11-19 15:40:01 +0800412 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
413 inPort, networkOflocalHostPorts,
414 localTunnelPorts,
415 type);
lishuai6c56f5e2015-11-17 16:38:19 +0800416 classifierService.programTunnelIn(deviceId, segmentationId,
417 localTunnelPorts,
418 type);
419 } else if (type == Objective.Operation.REMOVE) {
lishuai7dc63d92015-11-27 17:15:25 +0800420 vPortStore.remove(virtualPortId);
jiangruic69a7fd2015-11-19 15:40:01 +0800421 if (networkOflocalHostPorts != null) {
422 l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
423 inPort, networkOflocalHostPorts,
424 localTunnelPorts,
425 type);
426 networkOflocalHostPorts.remove(inPort);
427 if (networkOflocalHostPorts.isEmpty()) {
428 classifierService.programTunnelIn(deviceId, segmentationId,
429 localTunnelPorts,
430 type);
431 switchOfLocalHostPorts.get(deviceId).getNetworkOfLocalHostPorts()
432 .remove(virtualPort.networkId());
433 }
lishuai6c56f5e2015-11-17 16:38:19 +0800434 }
435 }
436
jiangruic69a7fd2015-11-19 15:40:01 +0800437 l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac,
438 type);
439
lishuai6c56f5e2015-11-17 16:38:19 +0800440 l2ForwardService.programTunnelBcastRules(deviceId, segmentationId,
441 networkOflocalHostPorts,
442 localTunnelPorts,
443 type);
444
445 programTunnelOuts(devices, ipAddress, segmentationId, mac,
446 type);
447
448 classifierService.programLocalIn(deviceId, segmentationId, inPort, mac,
449 appId, type);
450 }
451
452 private void programTunnelOuts(Iterable<Device> devices,
453 IpAddress ipAddress,
454 SegmentationId segmentationId,
455 MacAddress dstMac,
456 Objective.Operation type) {
jiangruic69a7fd2015-11-19 15:40:01 +0800457 String tunnelName = "vxlan-" + DEFAULT_IP;
lishuai6c56f5e2015-11-17 16:38:19 +0800458 Sets.newHashSet(devices).stream()
jiangruic69a7fd2015-11-19 15:40:01 +0800459 .filter(d -> d.type() == Device.Type.CONTROLLER)
460 .filter(d -> !("ovsdb:" + ipAddress).equals(d.id().toString()))
461 .forEach(d -> {
lishuai6c56f5e2015-11-17 16:38:19 +0800462 DriverHandler handler = driverService.createHandler(d.id());
463 BridgeConfig bridgeConfig = handler
464 .behaviour(BridgeConfig.class);
465 Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
466 .getBridges();
467 Set<PortNumber> ports = bridgeConfig.getPortNumbers();
468 Iterator<BridgeDescription> it = bridgeDescriptions
469 .iterator();
470 if (it.hasNext()) {
471 BridgeDescription sw = it.next();
472 ports.stream()
473 .filter(p -> p.name()
474 .equalsIgnoreCase(tunnelName))
475 .forEach(p -> {
476 l2ForwardService.programTunnelOut(sw.deviceId(),
477 segmentationId, p,
jiangruic69a7fd2015-11-19 15:40:01 +0800478 dstMac, type, ipAddress);
lishuai6c56f5e2015-11-17 16:38:19 +0800479 });
480 }
481 });
482 }
483
484 private class InnerDeviceListener implements DeviceListener {
485
486 @Override
487 public void event(DeviceEvent event) {
488 Device device = event.subject();
489 if (Device.Type.CONTROLLER == device.type()) {
490 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
491 onControllerDetected(device);
492 }
493 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
494 if (deviceService.isAvailable(device.id())) {
495 onControllerDetected(device);
496 } else {
497 onControllerVanished(device);
498 }
499 }
500 } else if (Device.Type.SWITCH == device.type()) {
501 if (DeviceEvent.Type.DEVICE_ADDED == event.type()) {
502 onOvsDetected(device);
503 }
504 if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) {
505 if (deviceService.isAvailable(device.id())) {
506 onOvsDetected(device);
507 } else {
508 onOvsVanished(device);
509 }
510 }
511 } else {
512 log.info("Do nothing for this device type");
513 }
514 }
515 }
516
517 private class InnerHostListener implements HostListener {
518
519 @Override
520 public void event(HostEvent event) {
521 Host host = event.subject();
522 if (HostEvent.Type.HOST_ADDED == event.type()) {
523 onHostDetected(host);
524 } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
525 onHostVanished(host);
526 } else if (HostEvent.Type.HOST_UPDATED == event.type()) {
527 onHostVanished(host);
528 onHostDetected(host);
529 }
530 }
531
532 }
533
534 // Local Host Ports of Network.
535 private class NetworkOfLocalHostPorts {
536 private final Map<TenantNetworkId, Set<PortNumber>> networkOfLocalHostPorts =
537 new HashMap<TenantNetworkId, Set<PortNumber>>();
538
539 public Map<TenantNetworkId, Set<PortNumber>> getNetworkOfLocalHostPorts() {
540 return networkOfLocalHostPorts;
541 }
542 }
543
jiangruic69a7fd2015-11-19 15:40:01 +0800544 private void programGroupTable(DeviceId deviceId, ApplicationId appid,
545 PortNumber portNumber, Iterable<Device> devices, Objective.Operation type) {
546 if (type.equals(Objective.Operation.REMOVE)) {
547 return;
548 }
549
550 List<GroupBucket> buckets = Lists.newArrayList();
551 Sets.newHashSet(devices)
552 .stream()
553 .filter(d -> d.type() == Device.Type.CONTROLLER)
554 .filter(d -> !deviceId.equals(d.id()))
555 .forEach(d -> {
556 String ipAddress = d.annotations()
557 .value(CONTROLLER_IP_KEY);
558 Ip4Address dst = Ip4Address.valueOf(ipAddress);
559 Builder builder = DefaultTrafficTreatment.builder();
560
561 DriverHandler handler = driverService.createHandler(deviceId);
562 ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
563 ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
564 try {
565 treatment.setPropertyValue("tunnelDst", dst);
566 } catch (Exception e) {
567 log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
568 }
569
570 builder.extension(treatment, deviceId);
571 builder.setOutput(portNumber);
572 GroupBucket bucket = DefaultGroupBucket
573 .createAllGroupBucket(builder.build());
574 buckets.add(bucket);
575 });
576 final GroupKey key = new DefaultGroupKey(APP_ID.getBytes());
577 GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
578 GroupDescription.Type.ALL,
579 new GroupBuckets(buckets),
580 key,
581 L2ForwardServiceImpl.GROUP_ID,
582 appid);
583 groupService.addGroup(groupDescription);
584 }
lishuai6c56f5e2015-11-17 16:38:19 +0800585}