jiangrui
Committed by Gerrit Code Review

ONOS-3404 Change p2p tunnel to p2any tunnel by using set tunnel_dst in

flow.

Change-Id: I06cb6d42772434de9c016e795de5c6d8a6f45dfb
...@@ -15,12 +15,14 @@ ...@@ -15,12 +15,14 @@
15 */ 15 */
16 package org.onosproject.vtn.manager.impl; 16 package org.onosproject.vtn.manager.impl;
17 17
18 +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
18 import static org.slf4j.LoggerFactory.getLogger; 19 import static org.slf4j.LoggerFactory.getLogger;
19 20
20 import java.util.Collection; 21 import java.util.Collection;
21 import java.util.HashMap; 22 import java.util.HashMap;
22 import java.util.HashSet; 23 import java.util.HashSet;
23 import java.util.Iterator; 24 import java.util.Iterator;
25 +import java.util.List;
24 import java.util.Map; 26 import java.util.Map;
25 import java.util.Set; 27 import java.util.Set;
26 28
...@@ -30,6 +32,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -30,6 +32,7 @@ import org.apache.felix.scr.annotations.Deactivate;
30 import org.apache.felix.scr.annotations.Reference; 32 import org.apache.felix.scr.annotations.Reference;
31 import org.apache.felix.scr.annotations.ReferenceCardinality; 33 import org.apache.felix.scr.annotations.ReferenceCardinality;
32 import org.apache.felix.scr.annotations.Service; 34 import org.apache.felix.scr.annotations.Service;
35 +import org.onlab.packet.Ip4Address;
33 import org.onlab.packet.IpAddress; 36 import org.onlab.packet.IpAddress;
34 import org.onlab.packet.MacAddress; 37 import org.onlab.packet.MacAddress;
35 import org.onlab.util.KryoNamespace; 38 import org.onlab.util.KryoNamespace;
...@@ -43,6 +46,7 @@ import org.onosproject.net.Port; ...@@ -43,6 +46,7 @@ import org.onosproject.net.Port;
43 import org.onosproject.net.PortNumber; 46 import org.onosproject.net.PortNumber;
44 import org.onosproject.net.behaviour.BridgeConfig; 47 import org.onosproject.net.behaviour.BridgeConfig;
45 import org.onosproject.net.behaviour.BridgeDescription; 48 import org.onosproject.net.behaviour.BridgeDescription;
49 +import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
46 import org.onosproject.net.config.NetworkConfigService; 50 import org.onosproject.net.config.NetworkConfigService;
47 import org.onosproject.net.config.basics.BasicDeviceConfig; 51 import org.onosproject.net.config.basics.BasicDeviceConfig;
48 import org.onosproject.net.device.DeviceEvent; 52 import org.onosproject.net.device.DeviceEvent;
...@@ -50,15 +54,24 @@ import org.onosproject.net.device.DeviceListener; ...@@ -50,15 +54,24 @@ import org.onosproject.net.device.DeviceListener;
50 import org.onosproject.net.device.DeviceService; 54 import org.onosproject.net.device.DeviceService;
51 import org.onosproject.net.driver.DriverHandler; 55 import org.onosproject.net.driver.DriverHandler;
52 import org.onosproject.net.driver.DriverService; 56 import org.onosproject.net.driver.DriverService;
57 +import org.onosproject.net.flow.DefaultTrafficTreatment;
58 +import org.onosproject.net.flow.TrafficTreatment.Builder;
59 +import org.onosproject.net.flow.instructions.ExtensionTreatment;
53 import org.onosproject.net.flowobjective.Objective; 60 import org.onosproject.net.flowobjective.Objective;
61 +import org.onosproject.net.group.DefaultGroupBucket;
62 +import org.onosproject.net.group.DefaultGroupDescription;
63 +import org.onosproject.net.group.DefaultGroupKey;
64 +import org.onosproject.net.group.GroupBucket;
65 +import org.onosproject.net.group.GroupBuckets;
66 +import org.onosproject.net.group.GroupDescription;
67 +import org.onosproject.net.group.GroupKey;
68 +import org.onosproject.net.group.GroupService;
54 import org.onosproject.net.host.HostEvent; 69 import org.onosproject.net.host.HostEvent;
55 import org.onosproject.net.host.HostListener; 70 import org.onosproject.net.host.HostListener;
56 import org.onosproject.net.host.HostService; 71 import org.onosproject.net.host.HostService;
57 import org.onosproject.store.serializers.KryoNamespaces; 72 import org.onosproject.store.serializers.KryoNamespaces;
58 -import org.onosproject.store.service.ConsistentMap;
59 import org.onosproject.store.service.EventuallyConsistentMap; 73 import org.onosproject.store.service.EventuallyConsistentMap;
60 import org.onosproject.store.service.LogicalClockService; 74 import org.onosproject.store.service.LogicalClockService;
61 -import org.onosproject.store.service.Serializer;
62 import org.onosproject.store.service.StorageService; 75 import org.onosproject.store.service.StorageService;
63 import org.onosproject.vtn.manager.VTNService; 76 import org.onosproject.vtn.manager.VTNService;
64 import org.onosproject.vtn.table.ClassifierService; 77 import org.onosproject.vtn.table.ClassifierService;
...@@ -79,6 +92,7 @@ import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; ...@@ -79,6 +92,7 @@ import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
79 import org.onosproject.vtnrsc.virtualport.VirtualPortService; 92 import org.onosproject.vtnrsc.virtualport.VirtualPortService;
80 import org.slf4j.Logger; 93 import org.slf4j.Logger;
81 94
95 +import com.google.common.collect.Lists;
82 import com.google.common.collect.Sets; 96 import com.google.common.collect.Sets;
83 97
84 /** 98 /**
...@@ -120,6 +134,9 @@ public class VTNManager implements VTNService { ...@@ -120,6 +134,9 @@ public class VTNManager implements VTNService {
120 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 134 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
121 protected MastershipService mastershipService; 135 protected MastershipService mastershipService;
122 136
137 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
138 + protected GroupService groupService;
139 +
123 private ApplicationId appId; 140 private ApplicationId appId;
124 private ClassifierService classifierService; 141 private ClassifierService classifierService;
125 private L2ForwardService l2ForwardService; 142 private L2ForwardService l2ForwardService;
...@@ -133,9 +150,10 @@ public class VTNManager implements VTNService { ...@@ -133,9 +150,10 @@ public class VTNManager implements VTNService {
133 private static final String EX_PORT_NAME = "eth0"; 150 private static final String EX_PORT_NAME = "eth0";
134 private static final String SWITCHES_OF_CONTROLLER = "switchesOfController"; 151 private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
135 private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts"; 152 private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
153 + private static final String DEFAULT_IP = "0.0.0.0";
136 154
137 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController; 155 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
138 - private ConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts; 156 + private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
139 157
140 @Activate 158 @Activate
141 public void activate() { 159 public void activate() {
...@@ -162,9 +180,9 @@ public class VTNManager implements VTNService { ...@@ -162,9 +180,9 @@ public class VTNManager implements VTNService {
162 .build(); 180 .build();
163 181
164 switchOfLocalHostPorts = storageService 182 switchOfLocalHostPorts = storageService
165 - .<DeviceId, NetworkOfLocalHostPorts>consistentMapBuilder() 183 + .<DeviceId, NetworkOfLocalHostPorts>eventuallyConsistentMapBuilder()
166 - .withName(SWITCH_OF_LOCAL_HOST_PORTS) 184 + .withName(SWITCH_OF_LOCAL_HOST_PORTS).withSerializer(serializer)
167 - .withSerializer(Serializer.using(serializer.build())) 185 + .withTimestampProvider((k, v) -> clockService.getTimestamp())
168 .build(); 186 .build();
169 187
170 log.info("Started"); 188 log.info("Started");
...@@ -251,44 +269,10 @@ public class VTNManager implements VTNService { ...@@ -251,44 +269,10 @@ public class VTNManager implements VTNService {
251 269
252 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp, 270 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
253 DriverHandler localHandler) { 271 DriverHandler localHandler) {
254 - Iterable<Device> devices = deviceService.getAvailableDevices();
255 - Sets.newHashSet(devices).stream()
256 - .filter(d -> Device.Type.CONTROLLER == d.type())
257 - .filter(d -> !localDeviceId.equals(d.id())).forEach(d -> {
258 - DriverHandler tunHandler = driverService
259 - .createHandler(d.id());
260 - String remoteIpAddress = d.annotations()
261 - .value(CONTROLLER_IP_KEY);
262 - IpAddress remoteIp = IpAddress.valueOf(remoteIpAddress);
263 - if (remoteIp.toString()
264 - .equalsIgnoreCase(localIp.toString())) {
265 - log.error("The localIp and remoteIp are the same");
266 - return;
267 - }
268 - if (localHandler != null) {
269 - // Create tunnel in br-int on local controller
270 if (mastershipService.isLocalMaster(localDeviceId)) { 272 if (mastershipService.isLocalMaster(localDeviceId)) {
271 - VtnConfig.applyTunnelConfig(localHandler, localIp, remoteIp); 273 + VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP));
272 - log.info("Add tunnel between {} and {}", localIp, 274 + log.info("Add tunnel on {}", localIp);
273 - remoteIp);
274 - }
275 - // Create tunnel in br-int on other controllers
276 - if (mastershipService.isLocalMaster(d.id())) {
277 - VtnConfig.applyTunnelConfig(tunHandler, remoteIp,
278 - localIp);
279 - log.info("Add tunnel between {} and {}", remoteIp,
280 - localIp);
281 } 275 }
282 - } else {
283 - // remove tunnel in br-int on other controllers
284 - if (mastershipService.isLocalMaster(d.id())) {
285 - VtnConfig.removeTunnelConfig(tunHandler, remoteIp,
286 - localIp);
287 - log.info("Remove tunnel between {} and {}", remoteIp,
288 - localIp);
289 - }
290 - }
291 - });
292 } 276 }
293 277
294 private void applyTunnelOut(Device device, Objective.Operation type) { 278 private void applyTunnelOut(Device device, Objective.Operation type) {
...@@ -321,6 +305,7 @@ public class VTNManager implements VTNService { ...@@ -321,6 +305,7 @@ public class VTNManager implements VTNService {
321 DriverHandler handler = driverService.createHandler(localControllerId); 305 DriverHandler handler = driverService.createHandler(localControllerId);
322 Set<PortNumber> ports = VtnConfig.getPortNumbers(handler); 306 Set<PortNumber> ports = VtnConfig.getPortNumbers(handler);
323 Iterable<Host> allHosts = hostService.getHosts(); 307 Iterable<Host> allHosts = hostService.getHosts();
308 + String tunnelName = "vxlan-" + DEFAULT_IP;
324 if (allHosts != null) { 309 if (allHosts != null) {
325 Sets.newHashSet(allHosts).stream().forEach(host -> { 310 Sets.newHashSet(allHosts).stream().forEach(host -> {
326 MacAddress hostMac = host.mac(); 311 MacAddress hostMac = host.mac();
...@@ -346,13 +331,12 @@ public class VTNManager implements VTNService { ...@@ -346,13 +331,12 @@ public class VTNManager implements VTNService {
346 } 331 }
347 IpAddress remoteIpAddress = IpAddress 332 IpAddress remoteIpAddress = IpAddress
348 .valueOf(remoteControllerIp); 333 .valueOf(remoteControllerIp);
349 - String tunnelName = "vxlan-" + remoteIpAddress.toString();
350 ports.stream() 334 ports.stream()
351 .filter(p -> p.name().equalsIgnoreCase(tunnelName)) 335 .filter(p -> p.name().equalsIgnoreCase(tunnelName))
352 .forEach(p -> { 336 .forEach(p -> {
353 l2ForwardService 337 l2ForwardService
354 .programTunnelOut(device.id(), segmentationId, p, 338 .programTunnelOut(device.id(), segmentationId, p,
355 - hostMac, type); 339 + hostMac, type, remoteIpAddress);
356 }); 340 });
357 }); 341 });
358 } 342 }
...@@ -392,16 +376,11 @@ public class VTNManager implements VTNService { ...@@ -392,16 +376,11 @@ public class VTNManager implements VTNService {
392 Collection<PortNumber> localTunnelPorts = VtnData.getLocalTunnelPorts(ports); 376 Collection<PortNumber> localTunnelPorts = VtnData.getLocalTunnelPorts(ports);
393 // Get all the local vm's PortNumber in the current node 377 // Get all the local vm's PortNumber in the current node
394 Map<TenantNetworkId, Set<PortNumber>> localHostPorts = switchOfLocalHostPorts 378 Map<TenantNetworkId, Set<PortNumber>> localHostPorts = switchOfLocalHostPorts
395 - .get(deviceId).value().getNetworkOfLocalHostPorts(); 379 + .get(deviceId).getNetworkOfLocalHostPorts();
396 Set<PortNumber> networkOflocalHostPorts = localHostPorts.get(network.id()); 380 Set<PortNumber> networkOflocalHostPorts = localHostPorts.get(network.id());
397 - 381 + for (PortNumber p : localTunnelPorts) {
398 - l2ForwardService.programLocalBcastRules(deviceId, segmentationId, 382 + programGroupTable(deviceId, appId, p, devices, type);
399 - inPort, networkOflocalHostPorts, 383 + }
400 - localTunnelPorts,
401 - type);
402 -
403 - l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac,
404 - type);
405 384
406 if (type == Objective.Operation.ADD) { 385 if (type == Objective.Operation.ADD) {
407 if (networkOflocalHostPorts == null) { 386 if (networkOflocalHostPorts == null) {
...@@ -409,19 +388,32 @@ public class VTNManager implements VTNService { ...@@ -409,19 +388,32 @@ public class VTNManager implements VTNService {
409 localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts); 388 localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts);
410 } 389 }
411 networkOflocalHostPorts.add(inPort); 390 networkOflocalHostPorts.add(inPort);
391 + l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
392 + inPort, networkOflocalHostPorts,
393 + localTunnelPorts,
394 + type);
412 classifierService.programTunnelIn(deviceId, segmentationId, 395 classifierService.programTunnelIn(deviceId, segmentationId,
413 localTunnelPorts, 396 localTunnelPorts,
414 type); 397 type);
415 } else if (type == Objective.Operation.REMOVE) { 398 } else if (type == Objective.Operation.REMOVE) {
399 + if (networkOflocalHostPorts != null) {
400 + l2ForwardService.programLocalBcastRules(deviceId, segmentationId,
401 + inPort, networkOflocalHostPorts,
402 + localTunnelPorts,
403 + type);
416 networkOflocalHostPorts.remove(inPort); 404 networkOflocalHostPorts.remove(inPort);
417 if (networkOflocalHostPorts.isEmpty()) { 405 if (networkOflocalHostPorts.isEmpty()) {
418 classifierService.programTunnelIn(deviceId, segmentationId, 406 classifierService.programTunnelIn(deviceId, segmentationId,
419 localTunnelPorts, 407 localTunnelPorts,
420 - Objective.Operation.REMOVE); 408 + type);
421 - switchOfLocalHostPorts.get(deviceId).value().getNetworkOfLocalHostPorts() 409 + switchOfLocalHostPorts.get(deviceId).getNetworkOfLocalHostPorts()
422 .remove(virtualPort.networkId()); 410 .remove(virtualPort.networkId());
423 } 411 }
424 } 412 }
413 + }
414 +
415 + l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac,
416 + type);
425 417
426 l2ForwardService.programTunnelBcastRules(deviceId, segmentationId, 418 l2ForwardService.programTunnelBcastRules(deviceId, segmentationId,
427 networkOflocalHostPorts, 419 networkOflocalHostPorts,
...@@ -440,9 +432,11 @@ public class VTNManager implements VTNService { ...@@ -440,9 +432,11 @@ public class VTNManager implements VTNService {
440 SegmentationId segmentationId, 432 SegmentationId segmentationId,
441 MacAddress dstMac, 433 MacAddress dstMac,
442 Objective.Operation type) { 434 Objective.Operation type) {
443 - String tunnelName = "vxlan-" + ipAddress.toString(); 435 + String tunnelName = "vxlan-" + DEFAULT_IP;
444 Sets.newHashSet(devices).stream() 436 Sets.newHashSet(devices).stream()
445 - .filter(d -> d.type() == Device.Type.CONTROLLER).forEach(d -> { 437 + .filter(d -> d.type() == Device.Type.CONTROLLER)
438 + .filter(d -> !("ovsdb:" + ipAddress).equals(d.id().toString()))
439 + .forEach(d -> {
446 DriverHandler handler = driverService.createHandler(d.id()); 440 DriverHandler handler = driverService.createHandler(d.id());
447 BridgeConfig bridgeConfig = handler 441 BridgeConfig bridgeConfig = handler
448 .behaviour(BridgeConfig.class); 442 .behaviour(BridgeConfig.class);
...@@ -459,7 +453,7 @@ public class VTNManager implements VTNService { ...@@ -459,7 +453,7 @@ public class VTNManager implements VTNService {
459 .forEach(p -> { 453 .forEach(p -> {
460 l2ForwardService.programTunnelOut(sw.deviceId(), 454 l2ForwardService.programTunnelOut(sw.deviceId(),
461 segmentationId, p, 455 segmentationId, p,
462 - dstMac, type); 456 + dstMac, type, ipAddress);
463 }); 457 });
464 } 458 }
465 }); 459 });
...@@ -525,4 +519,45 @@ public class VTNManager implements VTNService { ...@@ -525,4 +519,45 @@ public class VTNManager implements VTNService {
525 } 519 }
526 } 520 }
527 521
522 + private void programGroupTable(DeviceId deviceId, ApplicationId appid,
523 + PortNumber portNumber, Iterable<Device> devices, Objective.Operation type) {
524 + if (type.equals(Objective.Operation.REMOVE)) {
525 + return;
526 + }
527 +
528 + List<GroupBucket> buckets = Lists.newArrayList();
529 + Sets.newHashSet(devices)
530 + .stream()
531 + .filter(d -> d.type() == Device.Type.CONTROLLER)
532 + .filter(d -> !deviceId.equals(d.id()))
533 + .forEach(d -> {
534 + String ipAddress = d.annotations()
535 + .value(CONTROLLER_IP_KEY);
536 + Ip4Address dst = Ip4Address.valueOf(ipAddress);
537 + Builder builder = DefaultTrafficTreatment.builder();
538 +
539 + DriverHandler handler = driverService.createHandler(deviceId);
540 + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
541 + ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
542 + try {
543 + treatment.setPropertyValue("tunnelDst", dst);
544 + } catch (Exception e) {
545 + log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
546 + }
547 +
548 + builder.extension(treatment, deviceId);
549 + builder.setOutput(portNumber);
550 + GroupBucket bucket = DefaultGroupBucket
551 + .createAllGroupBucket(builder.build());
552 + buckets.add(bucket);
553 + });
554 + final GroupKey key = new DefaultGroupKey(APP_ID.getBytes());
555 + GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
556 + GroupDescription.Type.ALL,
557 + new GroupBuckets(buckets),
558 + key,
559 + L2ForwardServiceImpl.GROUP_ID,
560 + appid);
561 + groupService.addGroup(groupDescription);
562 + }
528 } 563 }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.vtn.table; 16 package org.onosproject.vtn.table;
17 17
18 +import org.onlab.packet.IpAddress;
18 import org.onlab.packet.MacAddress; 19 import org.onlab.packet.MacAddress;
19 import org.onosproject.net.DeviceId; 20 import org.onosproject.net.DeviceId;
20 import org.onosproject.net.PortNumber; 21 import org.onosproject.net.PortNumber;
...@@ -22,13 +23,14 @@ import org.onosproject.net.flowobjective.Objective; ...@@ -22,13 +23,14 @@ import org.onosproject.net.flowobjective.Objective;
22 import org.onosproject.vtnrsc.SegmentationId; 23 import org.onosproject.vtnrsc.SegmentationId;
23 24
24 /** 25 /**
25 - * Applies L2 flows to the device. 26 + * Applies L2 flows to the device. L2Forward table is Table(50).
26 */ 27 */
27 public interface L2ForwardService { 28 public interface L2ForwardService {
28 29
29 /** 30 /**
30 - * The local broadcast rule that message matches Table(50) Match: broadcast 31 + * The local broadcast rule that message matches Table(50).
31 - * mac and vnid Action: output port. 32 + * Match: broadcast mac and vnid.
33 + * Action: set output port.
32 * 34 *
33 * @param deviceId Device Id 35 * @param deviceId Device Id
34 * @param segmentationId the vnid of the host belong to 36 * @param segmentationId the vnid of the host belong to
...@@ -45,8 +47,9 @@ public interface L2ForwardService { ...@@ -45,8 +47,9 @@ public interface L2ForwardService {
45 Objective.Operation type); 47 Objective.Operation type);
46 48
47 /** 49 /**
48 - * The tunnel broadcast rule that message matches Table(50) Match: broadcast 50 + * The tunnel broadcast rule that message matches Table(50).
49 - * mac and vnid Action: output port. 51 + * Match: broadcast mac and vnid.
52 + * Action: output port.
50 * 53 *
51 * @param deviceId Device Id 54 * @param deviceId Device Id
52 * @param segmentationId the vnid of the host belong to 55 * @param segmentationId the vnid of the host belong to
...@@ -61,8 +64,9 @@ public interface L2ForwardService { ...@@ -61,8 +64,9 @@ public interface L2ForwardService {
61 Objective.Operation type); 64 Objective.Operation type);
62 65
63 /** 66 /**
64 - * The local out rule that message matches. Table(50) Match: local host mac 67 + * The local out rule that message matches Table(50).
65 - * and vnid Action: output local host port. 68 + * Match: local host mac and vnid.
69 + * Action: output local host port.
66 * 70 *
67 * @param deviceId Device Id 71 * @param deviceId Device Id
68 * @param segmentationId the vnid of the host belong to 72 * @param segmentationId the vnid of the host belong to
...@@ -75,17 +79,19 @@ public interface L2ForwardService { ...@@ -75,17 +79,19 @@ public interface L2ForwardService {
75 Objective.Operation type); 79 Objective.Operation type);
76 80
77 /** 81 /**
78 - * The tunnel out rule that message matches. Table(50) Match: host mac and 82 + * The tunnel out rule that message matches Table(50).
79 - * vnid Action: output tunnel port. 83 + * Match: host mac and vnid.
84 + * Action: output tunnel port.
80 * 85 *
81 * @param deviceId Device Id 86 * @param deviceId Device Id
82 * @param segmentationId the vnid of the host belong to 87 * @param segmentationId the vnid of the host belong to
83 * @param tunnelOutPort the port of the tunnel 88 * @param tunnelOutPort the port of the tunnel
84 * @param dstMac the mac of the host 89 * @param dstMac the mac of the host
85 * @param type the operation of the flow 90 * @param type the operation of the flow
91 + * @param ipAddress the ipAddress of the node
86 */ 92 */
87 void programTunnelOut(DeviceId deviceId, SegmentationId segmentationId, 93 void programTunnelOut(DeviceId deviceId, SegmentationId segmentationId,
88 PortNumber tunnelOutPort, MacAddress dstMac, 94 PortNumber tunnelOutPort, MacAddress dstMac,
89 - Objective.Operation type); 95 + Objective.Operation type, IpAddress ipAddress);
90 96
91 } 97 }
......
...@@ -16,19 +16,28 @@ ...@@ -16,19 +16,28 @@
16 package org.onosproject.vtn.table.impl; 16 package org.onosproject.vtn.table.impl;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
19 import static org.slf4j.LoggerFactory.getLogger; 20 import static org.slf4j.LoggerFactory.getLogger;
20 21
21 import org.onlab.osgi.DefaultServiceDirectory; 22 import org.onlab.osgi.DefaultServiceDirectory;
22 import org.onlab.osgi.ServiceDirectory; 23 import org.onlab.osgi.ServiceDirectory;
24 +import org.onlab.packet.Ip4Address;
25 +import org.onlab.packet.IpAddress;
23 import org.onlab.packet.MacAddress; 26 import org.onlab.packet.MacAddress;
24 import org.onosproject.core.ApplicationId; 27 import org.onosproject.core.ApplicationId;
28 +import org.onosproject.core.DefaultGroupId;
25 import org.onosproject.net.DeviceId; 29 import org.onosproject.net.DeviceId;
26 import org.onosproject.net.PortNumber; 30 import org.onosproject.net.PortNumber;
31 +import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
32 +import org.onosproject.net.driver.DriverHandler;
33 +import org.onosproject.net.driver.DriverService;
27 import org.onosproject.net.flow.DefaultTrafficSelector; 34 import org.onosproject.net.flow.DefaultTrafficSelector;
28 import org.onosproject.net.flow.DefaultTrafficTreatment; 35 import org.onosproject.net.flow.DefaultTrafficTreatment;
29 import org.onosproject.net.flow.TrafficSelector; 36 import org.onosproject.net.flow.TrafficSelector;
30 import org.onosproject.net.flow.TrafficTreatment; 37 import org.onosproject.net.flow.TrafficTreatment;
38 +import org.onosproject.net.flow.TrafficTreatment.Builder;
31 import org.onosproject.net.flow.criteria.Criteria; 39 import org.onosproject.net.flow.criteria.Criteria;
40 +import org.onosproject.net.flow.instructions.ExtensionTreatment;
32 import org.onosproject.net.flowobjective.DefaultForwardingObjective; 41 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
33 import org.onosproject.net.flowobjective.FlowObjectiveService; 42 import org.onosproject.net.flowobjective.FlowObjectiveService;
34 import org.onosproject.net.flowobjective.ForwardingObjective; 43 import org.onosproject.net.flowobjective.ForwardingObjective;
...@@ -47,10 +56,10 @@ public final class L2ForwardServiceImpl implements L2ForwardService { ...@@ -47,10 +56,10 @@ public final class L2ForwardServiceImpl implements L2ForwardService {
47 private final Logger log = getLogger(getClass()); 56 private final Logger log = getLogger(getClass());
48 57
49 private static final int MAC_PRIORITY = 0xffff; 58 private static final int MAC_PRIORITY = 0xffff;
50 - 59 + public static final Integer GROUP_ID = 1;
51 private final FlowObjectiveService flowObjectiveService; 60 private final FlowObjectiveService flowObjectiveService;
52 private final ApplicationId appId; 61 private final ApplicationId appId;
53 - 62 + private final DriverService driverService;
54 /** 63 /**
55 * Constructor. 64 * Constructor.
56 * 65 *
...@@ -60,6 +69,7 @@ public final class L2ForwardServiceImpl implements L2ForwardService { ...@@ -60,6 +69,7 @@ public final class L2ForwardServiceImpl implements L2ForwardService {
60 this.appId = checkNotNull(appId, "ApplicationId can not be null"); 69 this.appId = checkNotNull(appId, "ApplicationId can not be null");
61 ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); 70 ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
62 this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); 71 this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
72 + this.driverService = serviceDirectory.get(DriverService.class);
63 } 73 }
64 74
65 @Override 75 @Override
...@@ -91,9 +101,7 @@ public final class L2ForwardServiceImpl implements L2ForwardService { ...@@ -91,9 +101,7 @@ public final class L2ForwardServiceImpl implements L2ForwardService {
91 if (type.equals(Objective.Operation.REMOVE) && inPort == lp) { 101 if (type.equals(Objective.Operation.REMOVE) && inPort == lp) {
92 flag = false; 102 flag = false;
93 } 103 }
94 - for (PortNumber outport : localTunnelPorts) { 104 + treatment.group(new DefaultGroupId(GROUP_ID));
95 - treatment.setOutput(outport);
96 - }
97 ForwardingObjective.Builder objective = DefaultForwardingObjective 105 ForwardingObjective.Builder objective = DefaultForwardingObjective
98 .builder().withTreatment(treatment.build()) 106 .builder().withTreatment(treatment.build())
99 .withSelector(selector).fromApp(appId).makePermanent() 107 .withSelector(selector).fromApp(appId).makePermanent()
...@@ -171,15 +179,26 @@ public final class L2ForwardServiceImpl implements L2ForwardService { ...@@ -171,15 +179,26 @@ public final class L2ForwardServiceImpl implements L2ForwardService {
171 public void programTunnelOut(DeviceId deviceId, 179 public void programTunnelOut(DeviceId deviceId,
172 SegmentationId segmentationId, 180 SegmentationId segmentationId,
173 PortNumber tunnelOutPort, MacAddress dstMac, 181 PortNumber tunnelOutPort, MacAddress dstMac,
174 - Objective.Operation type) { 182 + Objective.Operation type, IpAddress ipAddress) {
175 TrafficSelector selector = DefaultTrafficSelector.builder() 183 TrafficSelector selector = DefaultTrafficSelector.builder()
176 .matchEthDst(dstMac).add(Criteria.matchTunnelId(Long 184 .matchEthDst(dstMac).add(Criteria.matchTunnelId(Long
177 .parseLong(segmentationId.toString()))) 185 .parseLong(segmentationId.toString())))
178 .build(); 186 .build();
179 - TrafficTreatment treatment = DefaultTrafficTreatment.builder() 187 +
188 + DriverHandler handler = driverService.createHandler(deviceId);
189 + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
190 + ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
191 + try {
192 + treatment.setPropertyValue("tunnelDst", Ip4Address.valueOf(ipAddress.toString()));
193 + } catch (Exception e) {
194 + log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
195 + }
196 +
197 + Builder builder = DefaultTrafficTreatment.builder();
198 + builder.extension(treatment, deviceId)
180 .setOutput(tunnelOutPort).build(); 199 .setOutput(tunnelOutPort).build();
181 ForwardingObjective.Builder objective = DefaultForwardingObjective 200 ForwardingObjective.Builder objective = DefaultForwardingObjective
182 - .builder().withTreatment(treatment).withSelector(selector) 201 + .builder().withTreatment(builder.build()).withSelector(selector)
183 .fromApp(appId).withFlag(Flag.SPECIFIC) 202 .fromApp(appId).withFlag(Flag.SPECIFIC)
184 .withPriority(MAC_PRIORITY); 203 .withPriority(MAC_PRIORITY);
185 if (type.equals(Objective.Operation.ADD)) { 204 if (type.equals(Objective.Operation.ADD)) {
...@@ -189,5 +208,4 @@ public final class L2ForwardServiceImpl implements L2ForwardService { ...@@ -189,5 +208,4 @@ public final class L2ForwardServiceImpl implements L2ForwardService {
189 } 208 }
190 209
191 } 210 }
192 -
193 } 211 }
......
...@@ -15,9 +15,12 @@ ...@@ -15,9 +15,12 @@
15 */ 15 */
16 package org.onosproject.vtn.util; 16 package org.onosproject.vtn.util;
17 17
18 +import java.util.HashMap;
19 +import java.util.Map;
18 import java.util.Set; 20 import java.util.Set;
19 21
20 import org.onlab.packet.IpAddress; 22 import org.onlab.packet.IpAddress;
23 +import org.onosproject.net.DefaultAnnotations;
21 import org.onosproject.net.PortNumber; 24 import org.onosproject.net.PortNumber;
22 import org.onosproject.net.behaviour.BridgeConfig; 25 import org.onosproject.net.behaviour.BridgeConfig;
23 import org.onosproject.net.behaviour.BridgeName; 26 import org.onosproject.net.behaviour.BridgeName;
...@@ -26,6 +29,7 @@ import org.onosproject.net.behaviour.IpTunnelEndPoint; ...@@ -26,6 +29,7 @@ import org.onosproject.net.behaviour.IpTunnelEndPoint;
26 import org.onosproject.net.behaviour.TunnelConfig; 29 import org.onosproject.net.behaviour.TunnelConfig;
27 import org.onosproject.net.behaviour.TunnelDescription; 30 import org.onosproject.net.behaviour.TunnelDescription;
28 import org.onosproject.net.behaviour.TunnelEndPoint; 31 import org.onosproject.net.behaviour.TunnelEndPoint;
32 +import org.onosproject.net.behaviour.TunnelName;
29 import org.onosproject.net.driver.DriverHandler; 33 import org.onosproject.net.driver.DriverHandler;
30 34
31 /** 35 /**
...@@ -34,7 +38,13 @@ import org.onosproject.net.driver.DriverHandler; ...@@ -34,7 +38,13 @@ import org.onosproject.net.driver.DriverHandler;
34 public final class VtnConfig { 38 public final class VtnConfig {
35 39
36 private static final String DEFAULT_BRIDGE_NAME = "br-int"; 40 private static final String DEFAULT_BRIDGE_NAME = "br-int";
37 - 41 + private static final String DEFAULT_TUNNEL = "vxlan-0.0.0.0";
42 + private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() {
43 + {
44 + put("key", "flow");
45 + put("remote_ip", "flow");
46 + }
47 + };
38 /** 48 /**
39 * Constructs a vtn config object. Utility classes should not have a 49 * Constructs a vtn config object. Utility classes should not have a
40 * public or default constructor, otherwise IDE will compile unsuccessfully. This 50 * public or default constructor, otherwise IDE will compile unsuccessfully. This
...@@ -64,15 +74,19 @@ public final class VtnConfig { ...@@ -64,15 +74,19 @@ public final class VtnConfig {
64 */ 74 */
65 public static void applyTunnelConfig(DriverHandler handler, IpAddress srcIp, 75 public static void applyTunnelConfig(DriverHandler handler, IpAddress srcIp,
66 IpAddress dstIp) { 76 IpAddress dstIp) {
77 + DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder();
78 + for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) {
79 + optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key));
80 + }
67 TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class); 81 TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class);
68 TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp); 82 TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp);
69 - TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dstIp);
70 TunnelDescription tunnel = new DefaultTunnelDescription( 83 TunnelDescription tunnel = new DefaultTunnelDescription(
71 tunnelAsSrc, 84 tunnelAsSrc,
72 - tunnelAsDst, 85 + null,
73 TunnelDescription.Type.VXLAN, 86 TunnelDescription.Type.VXLAN,
74 - null); 87 + TunnelName.tunnelName(DEFAULT_TUNNEL),
75 - tunnelConfig.createTunnel(tunnel); 88 + optionBuilder.build());
89 + tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), tunnel);
76 } 90 }
77 91
78 /** 92 /**
......