Committed by
Gerrit Code Review
CORD-472 Added table 0 and physical access rules
Change-Id: I73fe01ec31cfc379b2a0c8ee99a781415fe70c5d
Showing
2 changed files
with
228 additions
and
94 deletions
... | @@ -426,7 +426,7 @@ public class CordVtn implements CordVtnService { | ... | @@ -426,7 +426,7 @@ public class CordVtn implements CordVtnService { |
426 | private void postInit(CordVtnNode node) { | 426 | private void postInit(CordVtnNode node) { |
427 | disconnect(node); | 427 | disconnect(node); |
428 | 428 | ||
429 | - ruleInstaller.init(node.intBrId(), getTunnelPort(node.intBrId())); | 429 | + ruleInstaller.init(node.intBrId(), node.phyPortName(), node.localIp()); |
430 | hostService.getConnectedHosts(node.intBrId()) | 430 | hostService.getConnectedHosts(node.intBrId()) |
431 | .stream() | 431 | .stream() |
432 | .forEach(vmHandler::connected); | 432 | .forEach(vmHandler::connected); | ... | ... |
... | @@ -18,11 +18,13 @@ package org.onosproject.cordvtn; | ... | @@ -18,11 +18,13 @@ package org.onosproject.cordvtn; |
18 | import com.google.common.collect.Lists; | 18 | import com.google.common.collect.Lists; |
19 | import com.google.common.collect.Maps; | 19 | import com.google.common.collect.Maps; |
20 | import org.onlab.packet.Ethernet; | 20 | import org.onlab.packet.Ethernet; |
21 | +import org.onlab.packet.IPv4; | ||
21 | import org.onlab.packet.Ip4Address; | 22 | import org.onlab.packet.Ip4Address; |
22 | import org.onlab.packet.Ip4Prefix; | 23 | import org.onlab.packet.Ip4Prefix; |
23 | import org.onlab.packet.IpAddress; | 24 | import org.onlab.packet.IpAddress; |
24 | import org.onlab.packet.IpPrefix; | 25 | import org.onlab.packet.IpPrefix; |
25 | import org.onlab.packet.MacAddress; | 26 | import org.onlab.packet.MacAddress; |
27 | +import org.onlab.packet.TpPort; | ||
26 | import org.onlab.util.ItemNotFoundException; | 28 | import org.onlab.util.ItemNotFoundException; |
27 | import org.onosproject.core.ApplicationId; | 29 | import org.onosproject.core.ApplicationId; |
28 | import org.onosproject.core.DefaultGroupId; | 30 | import org.onosproject.core.DefaultGroupId; |
... | @@ -94,15 +96,19 @@ public class CordVtnRuleInstaller { | ... | @@ -94,15 +96,19 @@ public class CordVtnRuleInstaller { |
94 | 96 | ||
95 | protected final Logger log = getLogger(getClass()); | 97 | protected final Logger log = getLogger(getClass()); |
96 | 98 | ||
97 | - private static final int TABLE_IN_PORT = 0; | 99 | + private static final int TABLE_FIRST = 0; |
98 | - private static final int TABLE_ACCESS_TYPE = 1; | 100 | + private static final int TABLE_IN_PORT = 1; |
99 | - private static final int TABLE_IN_SERVICE = 2; | 101 | + private static final int TABLE_ACCESS_TYPE = 2; |
100 | - private static final int TABLE_DST_IP = 3; | 102 | + private static final int TABLE_IN_SERVICE = 3; |
101 | - private static final int TABLE_TUNNEL_IN = 4; | 103 | + private static final int TABLE_DST_IP = 4; |
104 | + private static final int TABLE_TUNNEL_IN = 5; | ||
102 | 105 | ||
103 | private static final int DEFAULT_PRIORITY = 5000; | 106 | private static final int DEFAULT_PRIORITY = 5000; |
104 | private static final int LOWER_PRIORITY = 4000; | 107 | private static final int LOWER_PRIORITY = 4000; |
105 | private static final int LOWEST_PRIORITY = 0; | 108 | private static final int LOWEST_PRIORITY = 0; |
109 | + private static final int HIGHER_PRIORITY = 50000; | ||
110 | + | ||
111 | + private static final int VXLAN_UDP_PORT = 4789; | ||
106 | 112 | ||
107 | private final ApplicationId appId; | 113 | private final ApplicationId appId; |
108 | private final FlowRuleService flowRuleService; | 114 | private final FlowRuleService flowRuleService; |
... | @@ -141,13 +147,18 @@ public class CordVtnRuleInstaller { | ... | @@ -141,13 +147,18 @@ public class CordVtnRuleInstaller { |
141 | * Installs table miss rule to a give device. | 147 | * Installs table miss rule to a give device. |
142 | * | 148 | * |
143 | * @param deviceId device id to install the rules | 149 | * @param deviceId device id to install the rules |
144 | - * @param tunnelPort tunnel port number of the device | 150 | + * @param phyPortName physical port name |
151 | + * @param localIp local data plane ip address | ||
145 | */ | 152 | */ |
146 | - public void init(DeviceId deviceId, PortNumber tunnelPort) { | 153 | + public void init(DeviceId deviceId, String phyPortName, IpAddress localIp) { |
147 | // default is drop packets which can be accomplished without | 154 | // default is drop packets which can be accomplished without |
148 | // a table miss entry for all table. | 155 | // a table miss entry for all table. |
149 | - populateTunnelInPortRule(deviceId, tunnelPort); | 156 | + PortNumber tunnelPort = getTunnelPort(deviceId); |
150 | - processAccessTypeTable(deviceId); | 157 | + PortNumber phyPort = getPhyPort(deviceId, phyPortName); |
158 | + | ||
159 | + processFirstTable(deviceId, phyPort, localIp); | ||
160 | + processInPortTable(deviceId, tunnelPort, phyPort); | ||
161 | + processAccessTypeTable(deviceId, phyPort); | ||
151 | } | 162 | } |
152 | 163 | ||
153 | /** | 164 | /** |
... | @@ -376,109 +387,93 @@ public class CordVtnRuleInstaller { | ... | @@ -376,109 +387,93 @@ public class CordVtnRuleInstaller { |
376 | } | 387 | } |
377 | 388 | ||
378 | /** | 389 | /** |
379 | - * Creates a new group for a given service. | 390 | + * Populates default rules on the first table. |
391 | + * The rules are for shuttling vxlan-encapped packets and supporting physical | ||
392 | + * network connectivity. | ||
380 | * | 393 | * |
381 | - * @param deviceId device id to create a group | 394 | + * @param deviceId device id |
382 | - * @param service cord service | 395 | + * @param phyPort physical port number |
383 | - * @return group id, or null if it fails to create | 396 | + * @param localIp local data plane ip address |
384 | */ | 397 | */ |
385 | - private GroupId createServiceGroup(DeviceId deviceId, CordService service) { | 398 | + private void processFirstTable(DeviceId deviceId, PortNumber phyPort, IpAddress localIp) { |
386 | - checkNotNull(service); | 399 | + // take vxlan packet out onto the physical port |
387 | - | 400 | + TrafficSelector selector = DefaultTrafficSelector.builder() |
388 | - GroupKey groupKey = getGroupKey(service.id()); | 401 | + .matchInPort(PortNumber.LOCAL) |
389 | - Group group = groupService.getGroup(deviceId, groupKey); | 402 | + .build(); |
390 | - GroupId groupId = getGroupId(service.id(), deviceId); | ||
391 | - | ||
392 | - if (group != null) { | ||
393 | - log.debug("Group {} is already exist in {}", service.id(), deviceId); | ||
394 | - return groupId; | ||
395 | - } | ||
396 | - | ||
397 | - GroupBuckets buckets = getServiceGroupBuckets(deviceId, service.segmentationId(), service.hosts()); | ||
398 | - GroupDescription groupDescription = new DefaultGroupDescription( | ||
399 | - deviceId, | ||
400 | - GroupDescription.Type.SELECT, | ||
401 | - buckets, | ||
402 | - groupKey, | ||
403 | - groupId.id(), | ||
404 | - appId); | ||
405 | 403 | ||
406 | - groupService.addGroup(groupDescription); | 404 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
405 | + .setOutput(phyPort) | ||
406 | + .build(); | ||
407 | 407 | ||
408 | - return groupId; | 408 | + FlowRule flowRule = DefaultFlowRule.builder() |
409 | - } | 409 | + .fromApp(appId) |
410 | + .withSelector(selector) | ||
411 | + .withTreatment(treatment) | ||
412 | + .withPriority(HIGHER_PRIORITY) | ||
413 | + .forDevice(deviceId) | ||
414 | + .forTable(TABLE_FIRST) | ||
415 | + .makePermanent() | ||
416 | + .build(); | ||
410 | 417 | ||
411 | - /** | 418 | + processFlowRule(true, flowRule); |
412 | - * Returns group buckets for a given device. | ||
413 | - * | ||
414 | - * @param deviceId device id | ||
415 | - * @param tunnelId tunnel id | ||
416 | - * @param hosts list of host | ||
417 | - * @return group buckets | ||
418 | - */ | ||
419 | - private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId, Map<Host, IpAddress> hosts) { | ||
420 | - List<GroupBucket> buckets = Lists.newArrayList(); | ||
421 | 419 | ||
422 | - for (Map.Entry<Host, IpAddress> entry : hosts.entrySet()) { | 420 | + // take a vxlan encap'd packet through the Linux stack |
423 | - Host host = entry.getKey(); | 421 | + selector = DefaultTrafficSelector.builder() |
424 | - Ip4Address remoteIp = entry.getValue().getIp4Address(); | 422 | + .matchInPort(phyPort) |
425 | - DeviceId hostDevice = host.location().deviceId(); | 423 | + .matchEthType(Ethernet.TYPE_IPV4) |
424 | + .matchIPProtocol(IPv4.PROTOCOL_UDP) | ||
425 | + .matchUdpDst(TpPort.tpPort(VXLAN_UDP_PORT)) | ||
426 | + .build(); | ||
426 | 427 | ||
427 | - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment | 428 | + treatment = DefaultTrafficTreatment.builder() |
428 | - .builder() | 429 | + .setOutput(PortNumber.LOCAL) |
429 | - .setEthDst(host.mac()); | 430 | + .build(); |
430 | 431 | ||
431 | - if (deviceId.equals(hostDevice)) { | 432 | + flowRule = DefaultFlowRule.builder() |
432 | - tBuilder.setOutput(host.location().port()); | 433 | + .fromApp(appId) |
433 | - } else { | 434 | + .withSelector(selector) |
434 | - ExtensionTreatment tunnelDst = getTunnelDst(deviceId, remoteIp); | 435 | + .withTreatment(treatment) |
435 | - if (tunnelDst == null) { | 436 | + .withPriority(HIGHER_PRIORITY) |
436 | - continue; | 437 | + .forDevice(deviceId) |
437 | - } | 438 | + .forTable(TABLE_FIRST) |
439 | + .makePermanent() | ||
440 | + .build(); | ||
438 | 441 | ||
439 | - tBuilder.extension(tunnelDst, deviceId) | 442 | + processFlowRule(true, flowRule); |
440 | - .setTunnelId(tunnelId) | ||
441 | - .setOutput(getTunnelPort(hostDevice)); | ||
442 | - } | ||
443 | 443 | ||
444 | - buckets.add(DefaultGroupBucket.createSelectGroupBucket(tBuilder.build())); | 444 | + // take all else to the next table |
445 | - } | 445 | + selector = DefaultTrafficSelector.builder() |
446 | + .build(); | ||
446 | 447 | ||
447 | - return new GroupBuckets(buckets); | 448 | + treatment = DefaultTrafficTreatment.builder() |
448 | - } | 449 | + .transition(TABLE_IN_PORT) |
450 | + .build(); | ||
449 | 451 | ||
450 | - /** | 452 | + flowRule = DefaultFlowRule.builder() |
451 | - * Returns globally unique group ID. | 453 | + .fromApp(appId) |
452 | - * | 454 | + .withSelector(selector) |
453 | - * @param serviceId service id | 455 | + .withTreatment(treatment) |
454 | - * @param deviceId device id | 456 | + .withPriority(LOWEST_PRIORITY) |
455 | - * @return group id | 457 | + .forDevice(deviceId) |
456 | - */ | 458 | + .forTable(TABLE_FIRST) |
457 | - private GroupId getGroupId(CordServiceId serviceId, DeviceId deviceId) { | 459 | + .makePermanent() |
458 | - return new DefaultGroupId(Objects.hash(serviceId, deviceId)); | 460 | + .build(); |
459 | - } | ||
460 | 461 | ||
461 | - /** | 462 | + processFlowRule(true, flowRule); |
462 | - * Returns group key of a service. | ||
463 | - * | ||
464 | - * @param serviceId service id | ||
465 | - * @return group key | ||
466 | - */ | ||
467 | - private GroupKey getGroupKey(CordServiceId serviceId) { | ||
468 | - return new DefaultGroupKey(serviceId.id().getBytes()); | ||
469 | } | 463 | } |
470 | 464 | ||
471 | /** | 465 | /** |
472 | - * Forward table miss rules in ACCESS_TYPE table to IN_SERVICE table. | 466 | + * Forward table miss packets in ACCESS_TYPE table to physical port. |
473 | * | 467 | * |
474 | * @param deviceId device id | 468 | * @param deviceId device id |
469 | + * @param phyPort physical port number | ||
475 | */ | 470 | */ |
476 | - private void processAccessTypeTable(DeviceId deviceId) { | 471 | + private void processAccessTypeTable(DeviceId deviceId, PortNumber phyPort) { |
477 | TrafficSelector selector = DefaultTrafficSelector.builder() | 472 | TrafficSelector selector = DefaultTrafficSelector.builder() |
478 | .build(); | 473 | .build(); |
479 | 474 | ||
480 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 475 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
481 | - .transition(TABLE_IN_SERVICE) | 476 | + .setOutput(phyPort) |
482 | .build(); | 477 | .build(); |
483 | 478 | ||
484 | FlowRule flowRule = DefaultFlowRule.builder() | 479 | FlowRule flowRule = DefaultFlowRule.builder() |
... | @@ -495,18 +490,21 @@ public class CordVtnRuleInstaller { | ... | @@ -495,18 +490,21 @@ public class CordVtnRuleInstaller { |
495 | } | 490 | } |
496 | 491 | ||
497 | /** | 492 | /** |
498 | - * Populates rules for tunnel flows in port in IN_PORT table. | 493 | + * Populates default rules for IN_PORT table. |
499 | - * All flows from tunnel port are forwarded to TUNNEL_ID table. | 494 | + * All packets from tunnel port are forwarded to TUNNEL_ID table and all packets |
495 | + * from physical port to ACCESS_TYPE table. | ||
500 | * | 496 | * |
501 | * @param deviceId device id to install the rules | 497 | * @param deviceId device id to install the rules |
502 | - * @param tunnelPort tunnel port | 498 | + * @param tunnelPort tunnel port number |
499 | + * @param phyPort physical port number | ||
503 | */ | 500 | */ |
504 | - private void populateTunnelInPortRule(DeviceId deviceId, PortNumber tunnelPort) { | 501 | + private void processInPortTable(DeviceId deviceId, PortNumber tunnelPort, PortNumber phyPort) { |
505 | checkNotNull(tunnelPort); | 502 | checkNotNull(tunnelPort); |
506 | 503 | ||
507 | TrafficSelector selector = DefaultTrafficSelector.builder() | 504 | TrafficSelector selector = DefaultTrafficSelector.builder() |
508 | .matchInPort(tunnelPort) | 505 | .matchInPort(tunnelPort) |
509 | .build(); | 506 | .build(); |
507 | + | ||
510 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 508 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
511 | .transition(TABLE_TUNNEL_IN) | 509 | .transition(TABLE_TUNNEL_IN) |
512 | .build(); | 510 | .build(); |
... | @@ -522,6 +520,26 @@ public class CordVtnRuleInstaller { | ... | @@ -522,6 +520,26 @@ public class CordVtnRuleInstaller { |
522 | .build(); | 520 | .build(); |
523 | 521 | ||
524 | processFlowRule(true, flowRule); | 522 | processFlowRule(true, flowRule); |
523 | + | ||
524 | + selector = DefaultTrafficSelector.builder() | ||
525 | + .matchInPort(phyPort) | ||
526 | + .build(); | ||
527 | + | ||
528 | + treatment = DefaultTrafficTreatment.builder() | ||
529 | + .transition(TABLE_DST_IP) | ||
530 | + .build(); | ||
531 | + | ||
532 | + flowRule = DefaultFlowRule.builder() | ||
533 | + .fromApp(appId) | ||
534 | + .withSelector(selector) | ||
535 | + .withTreatment(treatment) | ||
536 | + .withPriority(DEFAULT_PRIORITY) | ||
537 | + .forDevice(deviceId) | ||
538 | + .forTable(TABLE_IN_PORT) | ||
539 | + .makePermanent() | ||
540 | + .build(); | ||
541 | + | ||
542 | + processFlowRule(true, flowRule); | ||
525 | } | 543 | } |
526 | 544 | ||
527 | /** | 545 | /** |
... | @@ -539,6 +557,7 @@ public class CordVtnRuleInstaller { | ... | @@ -539,6 +557,7 @@ public class CordVtnRuleInstaller { |
539 | .matchEthType(Ethernet.TYPE_IPV4) | 557 | .matchEthType(Ethernet.TYPE_IPV4) |
540 | .matchIPSrc(srcIp.toIpPrefix()) | 558 | .matchIPSrc(srcIp.toIpPrefix()) |
541 | .build(); | 559 | .build(); |
560 | + | ||
542 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 561 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
543 | .transition(TABLE_ACCESS_TYPE) | 562 | .transition(TABLE_ACCESS_TYPE) |
544 | .build(); | 563 | .build(); |
... | @@ -559,6 +578,7 @@ public class CordVtnRuleInstaller { | ... | @@ -559,6 +578,7 @@ public class CordVtnRuleInstaller { |
559 | selector = DefaultTrafficSelector.builder() | 578 | selector = DefaultTrafficSelector.builder() |
560 | .matchInPort(inPort) | 579 | .matchInPort(inPort) |
561 | .build(); | 580 | .build(); |
581 | + | ||
562 | treatment = DefaultTrafficTreatment.builder() | 582 | treatment = DefaultTrafficTreatment.builder() |
563 | .transition(TABLE_IN_SERVICE) | 583 | .transition(TABLE_IN_SERVICE) |
564 | .build(); | 584 | .build(); |
... | @@ -589,6 +609,7 @@ public class CordVtnRuleInstaller { | ... | @@ -589,6 +609,7 @@ public class CordVtnRuleInstaller { |
589 | .matchIPSrc(srcRange) | 609 | .matchIPSrc(srcRange) |
590 | .matchIPDst(dstRange) | 610 | .matchIPDst(dstRange) |
591 | .build(); | 611 | .build(); |
612 | + | ||
592 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 613 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
593 | .transition(TABLE_DST_IP) | 614 | .transition(TABLE_DST_IP) |
594 | .build(); | 615 | .build(); |
... | @@ -666,6 +687,7 @@ public class CordVtnRuleInstaller { | ... | @@ -666,6 +687,7 @@ public class CordVtnRuleInstaller { |
666 | TrafficSelector selector = DefaultTrafficSelector.builder() | 687 | TrafficSelector selector = DefaultTrafficSelector.builder() |
667 | .matchInPort(port) | 688 | .matchInPort(port) |
668 | .build(); | 689 | .build(); |
690 | + | ||
669 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 691 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
670 | .group(groupId) | 692 | .group(groupId) |
671 | .build(); | 693 | .build(); |
... | @@ -701,6 +723,7 @@ public class CordVtnRuleInstaller { | ... | @@ -701,6 +723,7 @@ public class CordVtnRuleInstaller { |
701 | .matchEthType(Ethernet.TYPE_IPV4) | 723 | .matchEthType(Ethernet.TYPE_IPV4) |
702 | .matchIPDst(dstIp.toIpPrefix()) | 724 | .matchIPDst(dstIp.toIpPrefix()) |
703 | .build(); | 725 | .build(); |
726 | + | ||
704 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 727 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
705 | .setEthDst(dstMac) | 728 | .setEthDst(dstMac) |
706 | .setOutput(inPort) | 729 | .setOutput(inPort) |
... | @@ -815,6 +838,24 @@ public class CordVtnRuleInstaller { | ... | @@ -815,6 +838,24 @@ public class CordVtnRuleInstaller { |
815 | } | 838 | } |
816 | 839 | ||
817 | /** | 840 | /** |
841 | + * Returns physical port name of a given device. | ||
842 | + * | ||
843 | + * @param deviceId device id | ||
844 | + * @param phyPortName physical port name | ||
845 | + * @return physical port number, or null if no physical port exists | ||
846 | + */ | ||
847 | + private PortNumber getPhyPort(DeviceId deviceId, String phyPortName) { | ||
848 | + try { | ||
849 | + return deviceService.getPorts(deviceId).stream() | ||
850 | + .filter(p -> p.annotations().value("portName").contains(phyPortName) && | ||
851 | + p.isEnabled()) | ||
852 | + .findFirst().get().number(); | ||
853 | + } catch (NoSuchElementException e) { | ||
854 | + return null; | ||
855 | + } | ||
856 | + } | ||
857 | + | ||
858 | + /** | ||
818 | * Returns the inport from a given flow rule if the rule contains the match of it. | 859 | * Returns the inport from a given flow rule if the rule contains the match of it. |
819 | * | 860 | * |
820 | * @param flowRule flow rule | 861 | * @param flowRule flow rule |
... | @@ -923,6 +964,99 @@ public class CordVtnRuleInstaller { | ... | @@ -923,6 +964,99 @@ public class CordVtnRuleInstaller { |
923 | } | 964 | } |
924 | 965 | ||
925 | /** | 966 | /** |
967 | + * Creates a new group for a given service. | ||
968 | + * | ||
969 | + * @param deviceId device id to create a group | ||
970 | + * @param service cord service | ||
971 | + * @return group id, or null if it fails to create | ||
972 | + */ | ||
973 | + private GroupId createServiceGroup(DeviceId deviceId, CordService service) { | ||
974 | + checkNotNull(service); | ||
975 | + | ||
976 | + GroupKey groupKey = getGroupKey(service.id()); | ||
977 | + Group group = groupService.getGroup(deviceId, groupKey); | ||
978 | + GroupId groupId = getGroupId(service.id(), deviceId); | ||
979 | + | ||
980 | + if (group != null) { | ||
981 | + log.debug("Group {} is already exist in {}", service.id(), deviceId); | ||
982 | + return groupId; | ||
983 | + } | ||
984 | + | ||
985 | + GroupBuckets buckets = getServiceGroupBuckets(deviceId, service.segmentationId(), service.hosts()); | ||
986 | + GroupDescription groupDescription = new DefaultGroupDescription( | ||
987 | + deviceId, | ||
988 | + GroupDescription.Type.SELECT, | ||
989 | + buckets, | ||
990 | + groupKey, | ||
991 | + groupId.id(), | ||
992 | + appId); | ||
993 | + | ||
994 | + groupService.addGroup(groupDescription); | ||
995 | + | ||
996 | + return groupId; | ||
997 | + } | ||
998 | + | ||
999 | + /** | ||
1000 | + * Returns group buckets for a given device. | ||
1001 | + * | ||
1002 | + * @param deviceId device id | ||
1003 | + * @param tunnelId tunnel id | ||
1004 | + * @param hosts list of host | ||
1005 | + * @return group buckets | ||
1006 | + */ | ||
1007 | + private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId, Map<Host, IpAddress> hosts) { | ||
1008 | + List<GroupBucket> buckets = Lists.newArrayList(); | ||
1009 | + | ||
1010 | + for (Map.Entry<Host, IpAddress> entry : hosts.entrySet()) { | ||
1011 | + Host host = entry.getKey(); | ||
1012 | + Ip4Address remoteIp = entry.getValue().getIp4Address(); | ||
1013 | + DeviceId hostDevice = host.location().deviceId(); | ||
1014 | + | ||
1015 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment | ||
1016 | + .builder() | ||
1017 | + .setEthDst(host.mac()); | ||
1018 | + | ||
1019 | + if (deviceId.equals(hostDevice)) { | ||
1020 | + tBuilder.setOutput(host.location().port()); | ||
1021 | + } else { | ||
1022 | + ExtensionTreatment tunnelDst = getTunnelDst(deviceId, remoteIp); | ||
1023 | + if (tunnelDst == null) { | ||
1024 | + continue; | ||
1025 | + } | ||
1026 | + | ||
1027 | + tBuilder.extension(tunnelDst, deviceId) | ||
1028 | + .setTunnelId(tunnelId) | ||
1029 | + .setOutput(getTunnelPort(hostDevice)); | ||
1030 | + } | ||
1031 | + | ||
1032 | + buckets.add(DefaultGroupBucket.createSelectGroupBucket(tBuilder.build())); | ||
1033 | + } | ||
1034 | + | ||
1035 | + return new GroupBuckets(buckets); | ||
1036 | + } | ||
1037 | + | ||
1038 | + /** | ||
1039 | + * Returns globally unique group ID. | ||
1040 | + * | ||
1041 | + * @param serviceId service id | ||
1042 | + * @param deviceId device id | ||
1043 | + * @return group id | ||
1044 | + */ | ||
1045 | + private GroupId getGroupId(CordServiceId serviceId, DeviceId deviceId) { | ||
1046 | + return new DefaultGroupId(Objects.hash(serviceId, deviceId)); | ||
1047 | + } | ||
1048 | + | ||
1049 | + /** | ||
1050 | + * Returns group key of a service. | ||
1051 | + * | ||
1052 | + * @param serviceId service id | ||
1053 | + * @return group key | ||
1054 | + */ | ||
1055 | + private GroupKey getGroupKey(CordServiceId serviceId) { | ||
1056 | + return new DefaultGroupKey(serviceId.id().getBytes()); | ||
1057 | + } | ||
1058 | + | ||
1059 | + /** | ||
926 | * Returns extension instruction to set tunnel destination. | 1060 | * Returns extension instruction to set tunnel destination. |
927 | * | 1061 | * |
928 | * @param deviceId device id | 1062 | * @param deviceId device id | ... | ... |
-
Please register or login to post a comment