Committed by
Gerrit Code Review
CORD-349 Support VLAN cross-connect traffic
Change related to this topic:
- Support VLAN cross-connect traffic
Utilize ports subjectClass to achieve. For non-xConnect port, set interface VLAN to -1
- Remove VLAN checking since we have multiple VLANs per port
- Hash the L2 interface group key generation to include VLAN as well
- Update the network-cfg.json sample
Other refactoring changes:
- Read next objective stores from srManager directly
- Use constant for flow priority
- CORD-267 Javadoc fix
Change-Id: I4ca8c2d9c8b3633a4a0101c5070d19343f7e5b90
Showing
31 changed files
with
675 additions
and
234 deletions
| ... | @@ -41,6 +41,10 @@ import java.util.Set; | ... | @@ -41,6 +41,10 @@ import java.util.Set; |
| 41 | 41 | ||
| 42 | import static com.google.common.base.Preconditions.checkNotNull; | 42 | import static com.google.common.base.Preconditions.checkNotNull; |
| 43 | 43 | ||
| 44 | +/** | ||
| 45 | + * Handler of ARP packets that responses or forwards ARP packets that | ||
| 46 | + * are sent to the controller. | ||
| 47 | + */ | ||
| 44 | public class ArpHandler { | 48 | public class ArpHandler { |
| 45 | 49 | ||
| 46 | private static Logger log = LoggerFactory.getLogger(ArpHandler.class); | 50 | private static Logger log = LoggerFactory.getLogger(ArpHandler.class); | ... | ... |
| ... | @@ -37,6 +37,10 @@ import java.util.concurrent.locks.ReentrantLock; | ... | @@ -37,6 +37,10 @@ import java.util.concurrent.locks.ReentrantLock; |
| 37 | 37 | ||
| 38 | import static com.google.common.base.Preconditions.checkNotNull; | 38 | import static com.google.common.base.Preconditions.checkNotNull; |
| 39 | 39 | ||
| 40 | +/** | ||
| 41 | + * Default routing handler that is responsible for route computing and | ||
| 42 | + * routing rule population. | ||
| 43 | + */ | ||
| 40 | public class DefaultRoutingHandler { | 44 | public class DefaultRoutingHandler { |
| 41 | 45 | ||
| 42 | private static Logger log = LoggerFactory | 46 | private static Logger log = LoggerFactory |
| ... | @@ -512,6 +516,7 @@ public class DefaultRoutingHandler { | ... | @@ -512,6 +516,7 @@ public class DefaultRoutingHandler { |
| 512 | */ | 516 | */ |
| 513 | public void populatePortAddressingRules(DeviceId deviceId) { | 517 | public void populatePortAddressingRules(DeviceId deviceId) { |
| 514 | rulePopulator.populateRouterMacVlanFilters(deviceId); | 518 | rulePopulator.populateRouterMacVlanFilters(deviceId); |
| 519 | + rulePopulator.populateXConnectVlanFilters(deviceId); | ||
| 515 | rulePopulator.populateRouterIpPunts(deviceId); | 520 | rulePopulator.populateRouterIpPunts(deviceId); |
| 516 | } | 521 | } |
| 517 | 522 | ... | ... |
| ... | @@ -20,7 +20,7 @@ import java.util.List; | ... | @@ -20,7 +20,7 @@ import java.util.List; |
| 20 | import static com.google.common.base.Preconditions.checkNotNull; | 20 | import static com.google.common.base.Preconditions.checkNotNull; |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | - * Tunnel class. | 23 | + * Default Tunnel class. |
| 24 | */ | 24 | */ |
| 25 | public class DefaultTunnel implements Tunnel { | 25 | public class DefaultTunnel implements Tunnel { |
| 26 | 26 | ... | ... |
| ... | @@ -38,6 +38,10 @@ import java.util.Set; | ... | @@ -38,6 +38,10 @@ import java.util.Set; |
| 38 | 38 | ||
| 39 | import static com.google.common.base.Preconditions.checkNotNull; | 39 | import static com.google.common.base.Preconditions.checkNotNull; |
| 40 | 40 | ||
| 41 | +/** | ||
| 42 | + * Handler of ICMP packets that responses or forwards ICMP packets that | ||
| 43 | + * are sent to the controller. | ||
| 44 | + */ | ||
| 41 | public class IcmpHandler { | 45 | public class IcmpHandler { |
| 42 | 46 | ||
| 43 | private static Logger log = LoggerFactory.getLogger(IcmpHandler.class); | 47 | private static Logger log = LoggerFactory.getLogger(IcmpHandler.class); | ... | ... |
| ... | @@ -37,6 +37,10 @@ import java.util.concurrent.ConcurrentLinkedQueue; | ... | @@ -37,6 +37,10 @@ import java.util.concurrent.ConcurrentLinkedQueue; |
| 37 | 37 | ||
| 38 | import static com.google.common.base.Preconditions.checkNotNull; | 38 | import static com.google.common.base.Preconditions.checkNotNull; |
| 39 | 39 | ||
| 40 | +/** | ||
| 41 | + * Handler of IP packets that forwards IP packets that are sent to the controller, | ||
| 42 | + * except the ICMP packets which are processed by @link{IcmpHandler}. | ||
| 43 | + */ | ||
| 40 | public class IpHandler { | 44 | public class IpHandler { |
| 41 | 45 | ||
| 42 | private static Logger log = LoggerFactory.getLogger(IpHandler.class); | 46 | private static Logger log = LoggerFactory.getLogger(IpHandler.class); | ... | ... |
| ... | @@ -24,16 +24,24 @@ public interface Policy { | ... | @@ -24,16 +24,24 @@ public interface Policy { |
| 24 | * Enums for policy type. | 24 | * Enums for policy type. |
| 25 | */ | 25 | */ |
| 26 | enum Type { | 26 | enum Type { |
| 27 | - // Tunnel flow policy type | 27 | + /** |
| 28 | + * Tunnel flow policy type. | ||
| 29 | + */ | ||
| 28 | TUNNEL_FLOW, | 30 | TUNNEL_FLOW, |
| 29 | 31 | ||
| 30 | - // Load balancing policy type | 32 | + /** |
| 33 | + * Load balancing policy type. | ||
| 34 | + */ | ||
| 31 | LOADBALANCE, | 35 | LOADBALANCE, |
| 32 | 36 | ||
| 33 | - // policy to avoid specific routers or links | 37 | + /** |
| 38 | + * policy to avoid specific routers or links. | ||
| 39 | + */ | ||
| 34 | AVOID, | 40 | AVOID, |
| 35 | 41 | ||
| 36 | - // Access Control policy type | 42 | + /** |
| 43 | + * Access Control policy type. | ||
| 44 | + */ | ||
| 37 | DENY | 45 | DENY |
| 38 | } | 46 | } |
| 39 | 47 | ... | ... |
| ... | @@ -48,18 +48,43 @@ public class PolicyHandler { | ... | @@ -48,18 +48,43 @@ public class PolicyHandler { |
| 48 | private FlowObjectiveService flowObjectiveService; | 48 | private FlowObjectiveService flowObjectiveService; |
| 49 | private TunnelHandler tunnelHandler; | 49 | private TunnelHandler tunnelHandler; |
| 50 | private final EventuallyConsistentMap<String, Policy> policyStore; | 50 | private final EventuallyConsistentMap<String, Policy> policyStore; |
| 51 | - | 51 | + /** |
| 52 | + * Result of policy creation. | ||
| 53 | + */ | ||
| 52 | public enum Result { | 54 | public enum Result { |
| 55 | + /** | ||
| 56 | + * Success. | ||
| 57 | + */ | ||
| 53 | SUCCESS, | 58 | SUCCESS, |
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * The same policy exists already. | ||
| 62 | + */ | ||
| 54 | POLICY_EXISTS, | 63 | POLICY_EXISTS, |
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * The policy ID exists already. | ||
| 67 | + */ | ||
| 55 | ID_EXISTS, | 68 | ID_EXISTS, |
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * Cannot find associated tunnel. | ||
| 72 | + */ | ||
| 56 | TUNNEL_NOT_FOUND, | 73 | TUNNEL_NOT_FOUND, |
| 74 | + | ||
| 75 | + /** | ||
| 76 | + * Policy was not found. | ||
| 77 | + */ | ||
| 57 | POLICY_NOT_FOUND, | 78 | POLICY_NOT_FOUND, |
| 79 | + | ||
| 80 | + /** | ||
| 81 | + * Policy type {} is not supported yet. | ||
| 82 | + */ | ||
| 58 | UNSUPPORTED_TYPE | 83 | UNSUPPORTED_TYPE |
| 59 | } | 84 | } |
| 60 | 85 | ||
| 61 | /** | 86 | /** |
| 62 | - * Creates a reference. | 87 | + * Constructs policy handler. |
| 63 | * | 88 | * |
| 64 | * @param appId segment routing application ID | 89 | * @param appId segment routing application ID |
| 65 | * @param deviceConfiguration DeviceConfiguration reference | 90 | * @param deviceConfiguration DeviceConfiguration reference | ... | ... |
| ... | @@ -23,6 +23,7 @@ import org.onlab.packet.IpPrefix; | ... | @@ -23,6 +23,7 @@ import org.onlab.packet.IpPrefix; |
| 23 | import org.onlab.packet.MacAddress; | 23 | import org.onlab.packet.MacAddress; |
| 24 | import org.onlab.packet.MplsLabel; | 24 | import org.onlab.packet.MplsLabel; |
| 25 | import org.onlab.packet.VlanId; | 25 | import org.onlab.packet.VlanId; |
| 26 | +import org.onosproject.net.ConnectPoint; | ||
| 26 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; | 27 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; |
| 27 | import org.onosproject.segmentrouting.config.DeviceConfiguration; | 28 | import org.onosproject.segmentrouting.config.DeviceConfiguration; |
| 28 | import org.onosproject.segmentrouting.grouphandler.NeighborSet; | 29 | import org.onosproject.segmentrouting.grouphandler.NeighborSet; |
| ... | @@ -49,11 +50,15 @@ import org.slf4j.LoggerFactory; | ... | @@ -49,11 +50,15 @@ import org.slf4j.LoggerFactory; |
| 49 | import java.util.ArrayList; | 50 | import java.util.ArrayList; |
| 50 | import java.util.HashSet; | 51 | import java.util.HashSet; |
| 51 | import java.util.List; | 52 | import java.util.List; |
| 53 | +import java.util.Map; | ||
| 52 | import java.util.Set; | 54 | import java.util.Set; |
| 53 | import java.util.concurrent.atomic.AtomicLong; | 55 | import java.util.concurrent.atomic.AtomicLong; |
| 54 | 56 | ||
| 55 | import static com.google.common.base.Preconditions.checkNotNull; | 57 | import static com.google.common.base.Preconditions.checkNotNull; |
| 56 | 58 | ||
| 59 | +/** | ||
| 60 | + * Populator of segment routing flow rules. | ||
| 61 | + */ | ||
| 57 | public class RoutingRulePopulator { | 62 | public class RoutingRulePopulator { |
| 58 | private static final Logger log = LoggerFactory | 63 | private static final Logger log = LoggerFactory |
| 59 | .getLogger(RoutingRulePopulator.class); | 64 | .getLogger(RoutingRulePopulator.class); |
| ... | @@ -63,6 +68,10 @@ public class RoutingRulePopulator { | ... | @@ -63,6 +68,10 @@ public class RoutingRulePopulator { |
| 63 | private DeviceConfiguration config; | 68 | private DeviceConfiguration config; |
| 64 | 69 | ||
| 65 | private static final int HIGHEST_PRIORITY = 0xffff; | 70 | private static final int HIGHEST_PRIORITY = 0xffff; |
| 71 | + // | ||
| 72 | + private static final int XCONNECT_PRIORITY = 1000; | ||
| 73 | + private static final int DEFAULT_PRIORITY = 100; | ||
| 74 | + private static final int FLOOD_PRIORITY = 5; | ||
| 66 | private static final long OFPP_MAX = 0xffffff00L; | 75 | private static final long OFPP_MAX = 0xffffff00L; |
| 67 | 76 | ||
| 68 | 77 | ||
| ... | @@ -120,6 +129,14 @@ public class RoutingRulePopulator { | ... | @@ -120,6 +129,14 @@ public class RoutingRulePopulator { |
| 120 | rulePopulationCounter.incrementAndGet(); | 129 | rulePopulationCounter.incrementAndGet(); |
| 121 | } | 130 | } |
| 122 | 131 | ||
| 132 | + /** | ||
| 133 | + * Removes IP rules for host when the host is gone. | ||
| 134 | + * | ||
| 135 | + * @param deviceId device ID of the device that host attaches to | ||
| 136 | + * @param hostIp IP address of the host | ||
| 137 | + * @param hostMac MAC address of the host | ||
| 138 | + * @param outPort port that host attaches to | ||
| 139 | + */ | ||
| 123 | public void revokeIpRuleForHost(DeviceId deviceId, Ip4Address hostIp, | 140 | public void revokeIpRuleForHost(DeviceId deviceId, Ip4Address hostIp, |
| 124 | MacAddress hostMac, PortNumber outPort) { | 141 | MacAddress hostMac, PortNumber outPort) { |
| 125 | log.debug("Revoke IP table entry for host {} at {}:{}", | 142 | log.debug("Revoke IP table entry for host {} at {}:{}", |
| ... | @@ -175,7 +192,7 @@ public class RoutingRulePopulator { | ... | @@ -175,7 +192,7 @@ public class RoutingRulePopulator { |
| 175 | .withSelector(selector) | 192 | .withSelector(selector) |
| 176 | .nextStep(portNextObjId) | 193 | .nextStep(portNextObjId) |
| 177 | .fromApp(srManager.appId).makePermanent() | 194 | .fromApp(srManager.appId).makePermanent() |
| 178 | - .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC); | 195 | + .withPriority(DEFAULT_PRIORITY).withFlag(ForwardingObjective.Flag.SPECIFIC); |
| 179 | } | 196 | } |
| 180 | 197 | ||
| 181 | /** | 198 | /** |
| ... | @@ -369,7 +386,7 @@ public class RoutingRulePopulator { | ... | @@ -369,7 +386,7 @@ public class RoutingRulePopulator { |
| 369 | for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) { | 386 | for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) { |
| 370 | ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId) | 387 | ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId) |
| 371 | .makePermanent()).withSelector(selector) | 388 | .makePermanent()).withSelector(selector) |
| 372 | - .withPriority(100)) | 389 | + .withPriority(DEFAULT_PRIORITY)) |
| 373 | .withFlag(ForwardingObjective.Flag.SPECIFIC); | 390 | .withFlag(ForwardingObjective.Flag.SPECIFIC); |
| 374 | srManager.flowObjectiveService. | 391 | srManager.flowObjectiveService. |
| 375 | forward(deviceId, | 392 | forward(deviceId, |
| ... | @@ -464,7 +481,8 @@ public class RoutingRulePopulator { | ... | @@ -464,7 +481,8 @@ public class RoutingRulePopulator { |
| 464 | FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); | 481 | FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); |
| 465 | fob.withKey(Criteria.matchInPort(port.number())) | 482 | fob.withKey(Criteria.matchInPort(port.number())) |
| 466 | .addCondition(Criteria.matchEthDst(deviceMac)) | 483 | .addCondition(Criteria.matchEthDst(deviceMac)) |
| 467 | - .addCondition(Criteria.matchVlanId(VlanId.NONE)); | 484 | + .addCondition(Criteria.matchVlanId(VlanId.NONE)) |
| 485 | + .withPriority(DEFAULT_PRIORITY); | ||
| 468 | // vlan assignment is valid only if this instance is master | 486 | // vlan assignment is valid only if this instance is master |
| 469 | if (srManager.mastershipService.isLocalMaster(deviceId)) { | 487 | if (srManager.mastershipService.isLocalMaster(deviceId)) { |
| 470 | TrafficTreatment tt = DefaultTrafficTreatment.builder() | 488 | TrafficTreatment tt = DefaultTrafficTreatment.builder() |
| ... | @@ -558,7 +576,7 @@ public class RoutingRulePopulator { | ... | @@ -558,7 +576,7 @@ public class RoutingRulePopulator { |
| 558 | fob.withFlag(Flag.SPECIFIC) | 576 | fob.withFlag(Flag.SPECIFIC) |
| 559 | .withSelector(sbuilder.build()) | 577 | .withSelector(sbuilder.build()) |
| 560 | .nextStep(nextId) | 578 | .nextStep(nextId) |
| 561 | - .withPriority(5) | 579 | + .withPriority(FLOOD_PRIORITY) |
| 562 | .fromApp(srManager.appId) | 580 | .fromApp(srManager.appId) |
| 563 | .makePermanent(); | 581 | .makePermanent(); |
| 564 | 582 | ||
| ... | @@ -572,6 +590,86 @@ public class RoutingRulePopulator { | ... | @@ -572,6 +590,86 @@ public class RoutingRulePopulator { |
| 572 | }); | 590 | }); |
| 573 | } | 591 | } |
| 574 | 592 | ||
| 593 | + /** | ||
| 594 | + * Creates a filtering objective to permit VLAN cross-connect traffic. | ||
| 595 | + * | ||
| 596 | + * @param deviceId the DPID of the switch | ||
| 597 | + */ | ||
| 598 | + public void populateXConnectVlanFilters(DeviceId deviceId) { | ||
| 599 | + Map<VlanId, List<ConnectPoint>> xConnectsForDevice = | ||
| 600 | + config.getXConnects(); | ||
| 601 | + xConnectsForDevice.forEach((vlanId, connectPoints) -> { | ||
| 602 | + // Only proceed the xConnect for given device | ||
| 603 | + for (ConnectPoint connectPoint : connectPoints) { | ||
| 604 | + if (!connectPoint.deviceId().equals(deviceId)) { | ||
| 605 | + return; | ||
| 606 | + } | ||
| 607 | + } | ||
| 608 | + | ||
| 609 | + connectPoints.forEach(connectPoint -> { | ||
| 610 | + FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); | ||
| 611 | + fob.withKey(Criteria.matchInPort(connectPoint.port())) | ||
| 612 | + .addCondition(Criteria.matchVlanId(vlanId)) | ||
| 613 | + .addCondition(Criteria.matchEthDst(MacAddress.NONE)) | ||
| 614 | + .withPriority(XCONNECT_PRIORITY); | ||
| 615 | + | ||
| 616 | + fob.permit().fromApp(srManager.appId); | ||
| 617 | + srManager.flowObjectiveService | ||
| 618 | + .filter(deviceId, fob.add(new SRObjectiveContext(deviceId, | ||
| 619 | + SRObjectiveContext.ObjectiveType.FILTER))); | ||
| 620 | + }); | ||
| 621 | + }); | ||
| 622 | + } | ||
| 623 | + | ||
| 624 | + /** | ||
| 625 | + * Populates a forwarding objective that points the VLAN cross-connect | ||
| 626 | + * packets to a broadcast group. | ||
| 627 | + * | ||
| 628 | + * @param deviceId switch ID to set the rules | ||
| 629 | + */ | ||
| 630 | + public void populateXConnectBroadcastRule(DeviceId deviceId) { | ||
| 631 | + Map<VlanId, List<ConnectPoint>> xConnects = | ||
| 632 | + config.getXConnects(); | ||
| 633 | + xConnects.forEach((vlanId, connectPoints) -> { | ||
| 634 | + // Only proceed the xConnect for given device | ||
| 635 | + for (ConnectPoint connectPoint : connectPoints) { | ||
| 636 | + if (!connectPoint.deviceId().equals(deviceId)) { | ||
| 637 | + return; | ||
| 638 | + } | ||
| 639 | + } | ||
| 640 | + | ||
| 641 | + int nextId = srManager.getXConnectNextObjectiveId(deviceId, vlanId); | ||
| 642 | + if (nextId < 0) { | ||
| 643 | + log.error("Cannot install cross-connect broadcast rule in dev:{} " + | ||
| 644 | + "due to missing nextId:{}", deviceId, nextId); | ||
| 645 | + return; | ||
| 646 | + } | ||
| 647 | + | ||
| 648 | + /* | ||
| 649 | + * Driver should treat objectives with MacAddress.NONE and !VlanId.NONE | ||
| 650 | + * as the VLAN cross-connect broadcast rules | ||
| 651 | + */ | ||
| 652 | + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); | ||
| 653 | + sbuilder.matchVlanId(vlanId); | ||
| 654 | + sbuilder.matchEthDst(MacAddress.NONE); | ||
| 655 | + | ||
| 656 | + ForwardingObjective.Builder fob = DefaultForwardingObjective.builder(); | ||
| 657 | + fob.withFlag(Flag.SPECIFIC) | ||
| 658 | + .withSelector(sbuilder.build()) | ||
| 659 | + .nextStep(nextId) | ||
| 660 | + .withPriority(DEFAULT_PRIORITY) | ||
| 661 | + .fromApp(srManager.appId) | ||
| 662 | + .makePermanent(); | ||
| 663 | + | ||
| 664 | + srManager.flowObjectiveService.forward( | ||
| 665 | + deviceId, | ||
| 666 | + fob.add(new SRObjectiveContext( | ||
| 667 | + deviceId, | ||
| 668 | + SRObjectiveContext.ObjectiveType.FORWARDING) | ||
| 669 | + ) | ||
| 670 | + ); | ||
| 671 | + }); | ||
| 672 | + } | ||
| 575 | 673 | ||
| 576 | private static class SRObjectiveContext implements ObjectiveContext { | 674 | private static class SRObjectiveContext implements ObjectiveContext { |
| 577 | enum ObjectiveType { | 675 | enum ObjectiveType { | ... | ... |
| ... | @@ -69,7 +69,6 @@ import org.onosproject.net.device.DeviceListener; | ... | @@ -69,7 +69,6 @@ import org.onosproject.net.device.DeviceListener; |
| 69 | import org.onosproject.net.device.DeviceService; | 69 | import org.onosproject.net.device.DeviceService; |
| 70 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 70 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
| 71 | import org.onosproject.net.host.HostService; | 71 | import org.onosproject.net.host.HostService; |
| 72 | -import org.onosproject.net.intent.IntentService; | ||
| 73 | import org.onosproject.net.link.LinkEvent; | 72 | import org.onosproject.net.link.LinkEvent; |
| 74 | import org.onosproject.net.link.LinkListener; | 73 | import org.onosproject.net.link.LinkListener; |
| 75 | import org.onosproject.net.link.LinkService; | 74 | import org.onosproject.net.link.LinkService; |
| ... | @@ -77,8 +76,8 @@ import org.onosproject.net.packet.InboundPacket; | ... | @@ -77,8 +76,8 @@ import org.onosproject.net.packet.InboundPacket; |
| 77 | import org.onosproject.net.packet.PacketContext; | 76 | import org.onosproject.net.packet.PacketContext; |
| 78 | import org.onosproject.net.packet.PacketProcessor; | 77 | import org.onosproject.net.packet.PacketProcessor; |
| 79 | import org.onosproject.net.packet.PacketService; | 78 | import org.onosproject.net.packet.PacketService; |
| 80 | -import org.onosproject.net.topology.TopologyService; | ||
| 81 | import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey; | 79 | import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey; |
| 80 | +import org.onosproject.segmentrouting.grouphandler.XConnectNextObjectiveStoreKey; | ||
| 82 | import org.onosproject.store.service.EventuallyConsistentMap; | 81 | import org.onosproject.store.service.EventuallyConsistentMap; |
| 83 | import org.onosproject.store.service.EventuallyConsistentMapBuilder; | 82 | import org.onosproject.store.service.EventuallyConsistentMapBuilder; |
| 84 | import org.onosproject.store.service.StorageService; | 83 | import org.onosproject.store.service.StorageService; |
| ... | @@ -102,6 +101,9 @@ import java.util.concurrent.TimeUnit; | ... | @@ -102,6 +101,9 @@ import java.util.concurrent.TimeUnit; |
| 102 | 101 | ||
| 103 | @Service | 102 | @Service |
| 104 | @Component(immediate = true) | 103 | @Component(immediate = true) |
| 104 | +/** | ||
| 105 | + * Segment routing manager. | ||
| 106 | + */ | ||
| 105 | public class SegmentRoutingManager implements SegmentRoutingService { | 107 | public class SegmentRoutingManager implements SegmentRoutingService { |
| 106 | 108 | ||
| 107 | private static Logger log = LoggerFactory | 109 | private static Logger log = LoggerFactory |
| ... | @@ -111,15 +113,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -111,15 +113,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 111 | protected CoreService coreService; | 113 | protected CoreService coreService; |
| 112 | 114 | ||
| 113 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 115 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 114 | - protected TopologyService topologyService; | ||
| 115 | - | ||
| 116 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 117 | protected PacketService packetService; | 116 | protected PacketService packetService; |
| 118 | 117 | ||
| 119 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 118 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 120 | - protected IntentService intentService; | ||
| 121 | - | ||
| 122 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 123 | protected HostService hostService; | 119 | protected HostService hostService; |
| 124 | 120 | ||
| 125 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 121 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| ... | @@ -157,20 +153,31 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -157,20 +153,31 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 157 | @SuppressWarnings("rawtypes") | 153 | @SuppressWarnings("rawtypes") |
| 158 | private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); | 154 | private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); |
| 159 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = | 155 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = |
| 160 | - new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); | 156 | + new ConcurrentHashMap<>(); |
| 161 | - // Per device next objective ID store with (device id + neighbor set) as key | 157 | + /** |
| 162 | - private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> | 158 | + * Per device next objective ID store with (device id + neighbor set) as key. |
| 159 | + */ | ||
| 160 | + public EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> | ||
| 163 | nsNextObjStore = null; | 161 | nsNextObjStore = null; |
| 164 | - // Per device next objective ID store with (device id + subnet) as key | 162 | + /** |
| 165 | - private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> | 163 | + * Per device next objective ID store with (device id + subnet) as key. |
| 164 | + */ | ||
| 165 | + public EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> | ||
| 166 | subnetNextObjStore = null; | 166 | subnetNextObjStore = null; |
| 167 | - // Per device next objective ID store with (device id + port) as key | 167 | + /** |
| 168 | - private EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer> | 168 | + * Per device next objective ID store with (device id + port) as key. |
| 169 | + */ | ||
| 170 | + public EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer> | ||
| 169 | portNextObjStore = null; | 171 | portNextObjStore = null; |
| 172 | + /** | ||
| 173 | + * Per cross-connect objective ID store with VLAN ID as key. | ||
| 174 | + */ | ||
| 175 | + public EventuallyConsistentMap<XConnectNextObjectiveStoreKey, Integer> | ||
| 176 | + xConnectNextObjStore = null; | ||
| 170 | // Per device, per-subnet assigned-vlans store, with (device id + subnet | 177 | // Per device, per-subnet assigned-vlans store, with (device id + subnet |
| 171 | // IPv4 prefix) as key | 178 | // IPv4 prefix) as key |
| 172 | private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId> | 179 | private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId> |
| 173 | - subnetVidStore = null; | 180 | + subnetVidStore = null; |
| 174 | private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; | 181 | private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; |
| 175 | private EventuallyConsistentMap<String, Policy> policyStore = null; | 182 | private EventuallyConsistentMap<String, Policy> policyStore = null; |
| 176 | 183 | ||
| ... | @@ -204,7 +211,13 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -204,7 +211,13 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 204 | 211 | ||
| 205 | private KryoNamespace.Builder kryoBuilder = null; | 212 | private KryoNamespace.Builder kryoBuilder = null; |
| 206 | 213 | ||
| 214 | + /** | ||
| 215 | + * The starting value of per-subnet VLAN ID assignment. | ||
| 216 | + */ | ||
| 207 | private static final short ASSIGNED_VLAN_START = 4093; | 217 | private static final short ASSIGNED_VLAN_START = 4093; |
| 218 | + /** | ||
| 219 | + * The default VLAN ID assigned to the interfaces without subnet config. | ||
| 220 | + */ | ||
| 208 | public static final short ASSIGNED_VLAN_NO_SUBNET = 4094; | 221 | public static final short ASSIGNED_VLAN_NO_SUBNET = 4094; |
| 209 | 222 | ||
| 210 | @Activate | 223 | @Activate |
| ... | @@ -262,6 +275,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -262,6 +275,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 262 | .withTimestampProvider((k, v) -> new WallClockTimestamp()) | 275 | .withTimestampProvider((k, v) -> new WallClockTimestamp()) |
| 263 | .build(); | 276 | .build(); |
| 264 | 277 | ||
| 278 | + log.debug("Creating EC map xconnectnextobjectivestore"); | ||
| 279 | + EventuallyConsistentMapBuilder<XConnectNextObjectiveStoreKey, Integer> | ||
| 280 | + xConnectNextObjStoreBuilder = storageService.eventuallyConsistentMapBuilder(); | ||
| 281 | + xConnectNextObjStore = xConnectNextObjStoreBuilder | ||
| 282 | + .withName("xconnectnextobjectivestore") | ||
| 283 | + .withSerializer(kryoBuilder) | ||
| 284 | + .withTimestampProvider((k, v) -> new WallClockTimestamp()) | ||
| 285 | + .build(); | ||
| 286 | + | ||
| 265 | EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder = | 287 | EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder = |
| 266 | storageService.eventuallyConsistentMapBuilder(); | 288 | storageService.eventuallyConsistentMapBuilder(); |
| 267 | tunnelStore = tunnelMapBuilder | 289 | tunnelStore = tunnelMapBuilder |
| ... | @@ -394,9 +416,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -394,9 +416,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 394 | * Vlan id 4094 expected to be used for all ports that are not assigned subnets. | 416 | * Vlan id 4094 expected to be used for all ports that are not assigned subnets. |
| 395 | * Vlan id 4095 is reserved and unused. Only a single vlan id is assigned | 417 | * Vlan id 4095 is reserved and unused. Only a single vlan id is assigned |
| 396 | * per subnet. | 418 | * per subnet. |
| 397 | - * XXX This method should avoid any vlans configured on the ports, but | ||
| 398 | - * currently the app works only on untagged packets and as a result | ||
| 399 | - * ignores any vlan configuration. | ||
| 400 | * | 419 | * |
| 401 | * @param deviceId switch dpid | 420 | * @param deviceId switch dpid |
| 402 | * @param subnet IPv4 prefix for which assigned vlan is desired | 421 | * @param subnet IPv4 prefix for which assigned vlan is desired |
| ... | @@ -404,6 +423,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -404,6 +423,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 404 | * null if no vlan assignment was found and this instance is not | 423 | * null if no vlan assignment was found and this instance is not |
| 405 | * the master for the device. | 424 | * the master for the device. |
| 406 | */ | 425 | */ |
| 426 | + // TODO: We should avoid assigning VLAN IDs that are used by VLAN cross-connection. | ||
| 407 | public VlanId getSubnetAssignedVlanId(DeviceId deviceId, Ip4Prefix subnet) { | 427 | public VlanId getSubnetAssignedVlanId(DeviceId deviceId, Ip4Prefix subnet) { |
| 408 | VlanId assignedVid = subnetVidStore.get(new SubnetAssignedVidStoreKey( | 428 | VlanId assignedVid = subnetVidStore.get(new SubnetAssignedVidStoreKey( |
| 409 | deviceId, subnet)); | 429 | deviceId, subnet)); |
| ... | @@ -508,7 +528,26 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -508,7 +528,26 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 508 | if (ghdlr != null) { | 528 | if (ghdlr != null) { |
| 509 | return ghdlr.getPortNextObjectiveId(portNum, treatment, meta); | 529 | return ghdlr.getPortNextObjectiveId(portNum, treatment, meta); |
| 510 | } else { | 530 | } else { |
| 511 | - log.warn("getPortNextObjectiveId query - groupHandler for device {}" | 531 | + log.warn("getPortNextObjectiveId query - groupHandler for device {}" |
| 532 | + + " not found", deviceId); | ||
| 533 | + return -1; | ||
| 534 | + } | ||
| 535 | + } | ||
| 536 | + | ||
| 537 | + /** | ||
| 538 | + * Returns the next objective ID of type broadcast associated with the VLAN | ||
| 539 | + * cross-connection. | ||
| 540 | + * | ||
| 541 | + * @param deviceId Device ID for the cross-connection | ||
| 542 | + * @param vlanId VLAN ID for the cross-connection | ||
| 543 | + * @return next objective ID or -1 if it was not found | ||
| 544 | + */ | ||
| 545 | + public int getXConnectNextObjectiveId(DeviceId deviceId, VlanId vlanId) { | ||
| 546 | + DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId); | ||
| 547 | + if (ghdlr != null) { | ||
| 548 | + return ghdlr.getXConnectNextObjectiveId(vlanId); | ||
| 549 | + } else { | ||
| 550 | + log.warn("getPortNextObjectiveId query - groupHandler for device {}" | ||
| 512 | + " not found", deviceId); | 551 | + " not found", deviceId); |
| 513 | return -1; | 552 | return -1; |
| 514 | } | 553 | } |
| ... | @@ -707,9 +746,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -707,9 +746,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 707 | deviceConfiguration, | 746 | deviceConfiguration, |
| 708 | linkService, | 747 | linkService, |
| 709 | flowObjectiveService, | 748 | flowObjectiveService, |
| 710 | - nsNextObjStore, | ||
| 711 | - subnetNextObjStore, | ||
| 712 | - portNextObjStore, | ||
| 713 | this); | 749 | this); |
| 714 | } catch (DeviceConfigNotFoundException e) { | 750 | } catch (DeviceConfigNotFoundException e) { |
| 715 | log.warn(e.getMessage() + " Aborting processDeviceAdded."); | 751 | log.warn(e.getMessage() + " Aborting processDeviceAdded."); |
| ... | @@ -727,6 +763,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -727,6 +763,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 727 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | 763 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); |
| 728 | groupHandler.createGroupsFromSubnetConfig(); | 764 | groupHandler.createGroupsFromSubnetConfig(); |
| 729 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); | 765 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); |
| 766 | + groupHandler.createGroupsForXConnect(device.id()); | ||
| 767 | + routingRulePopulator.populateXConnectBroadcastRule(device.id()); | ||
| 730 | } | 768 | } |
| 731 | } | 769 | } |
| 732 | 770 | ||
| ... | @@ -742,10 +780,18 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -742,10 +780,18 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 742 | private class InternalConfigListener implements NetworkConfigListener { | 780 | private class InternalConfigListener implements NetworkConfigListener { |
| 743 | SegmentRoutingManager segmentRoutingManager; | 781 | SegmentRoutingManager segmentRoutingManager; |
| 744 | 782 | ||
| 783 | + /** | ||
| 784 | + * Constructs the internal network config listener. | ||
| 785 | + * | ||
| 786 | + * @param srMgr segment routing manager | ||
| 787 | + */ | ||
| 745 | public InternalConfigListener(SegmentRoutingManager srMgr) { | 788 | public InternalConfigListener(SegmentRoutingManager srMgr) { |
| 746 | this.segmentRoutingManager = srMgr; | 789 | this.segmentRoutingManager = srMgr; |
| 747 | } | 790 | } |
| 748 | 791 | ||
| 792 | + /** | ||
| 793 | + * Reads network config and initializes related data structure accordingly. | ||
| 794 | + */ | ||
| 749 | public void configureNetwork() { | 795 | public void configureNetwork() { |
| 750 | deviceConfiguration = new DeviceConfiguration(segmentRoutingManager.cfgService); | 796 | deviceConfiguration = new DeviceConfiguration(segmentRoutingManager.cfgService); |
| 751 | 797 | ||
| ... | @@ -777,9 +823,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -777,9 +823,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 777 | deviceConfiguration, | 823 | deviceConfiguration, |
| 778 | linkService, | 824 | linkService, |
| 779 | flowObjectiveService, | 825 | flowObjectiveService, |
| 780 | - nsNextObjStore, | ||
| 781 | - subnetNextObjStore, | ||
| 782 | - portNextObjStore, | ||
| 783 | segmentRoutingManager); | 826 | segmentRoutingManager); |
| 784 | } catch (DeviceConfigNotFoundException e) { | 827 | } catch (DeviceConfigNotFoundException e) { |
| 785 | log.warn(e.getMessage() + " Aborting configureNetwork."); | 828 | log.warn(e.getMessage() + " Aborting configureNetwork."); |
| ... | @@ -798,6 +841,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -798,6 +841,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 798 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | 841 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); |
| 799 | groupHandler.createGroupsFromSubnetConfig(); | 842 | groupHandler.createGroupsFromSubnetConfig(); |
| 800 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); | 843 | routingRulePopulator.populateSubnetBroadcastRule(device.id()); |
| 844 | + groupHandler.createGroupsForXConnect(device.id()); | ||
| 845 | + routingRulePopulator.populateXConnectBroadcastRule(device.id()); | ||
| 801 | } | 846 | } |
| 802 | } | 847 | } |
| 803 | 848 | ... | ... |
| ... | @@ -6,13 +6,18 @@ import org.onlab.packet.Ip4Prefix; | ... | @@ -6,13 +6,18 @@ import org.onlab.packet.Ip4Prefix; |
| 6 | import org.onosproject.net.DeviceId; | 6 | import org.onosproject.net.DeviceId; |
| 7 | 7 | ||
| 8 | /** | 8 | /** |
| 9 | - * Class definition for key used to map per device subnets to assigned Vlan ids. | 9 | + * Key of assigned VLAN ID store. |
| 10 | - * | ||
| 11 | */ | 10 | */ |
| 12 | public class SubnetAssignedVidStoreKey { | 11 | public class SubnetAssignedVidStoreKey { |
| 13 | private final DeviceId deviceId; | 12 | private final DeviceId deviceId; |
| 14 | private final Ip4Prefix subnet; | 13 | private final Ip4Prefix subnet; |
| 15 | 14 | ||
| 15 | + /** | ||
| 16 | + * Constructs the key of per subnet VLAN ID store. | ||
| 17 | + * | ||
| 18 | + * @param deviceId device ID of the VLAN cross-connection | ||
| 19 | + * @param subnet subnet information | ||
| 20 | + */ | ||
| 16 | public SubnetAssignedVidStoreKey(DeviceId deviceId, Ip4Prefix subnet) { | 21 | public SubnetAssignedVidStoreKey(DeviceId deviceId, Ip4Prefix subnet) { |
| 17 | this.deviceId = deviceId; | 22 | this.deviceId = deviceId; |
| 18 | this.subnet = subnet; | 23 | this.subnet = subnet; | ... | ... |
| ... | @@ -43,16 +43,54 @@ public class TunnelHandler { | ... | @@ -43,16 +43,54 @@ public class TunnelHandler { |
| 43 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap; | 43 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap; |
| 44 | private LinkService linkService; | 44 | private LinkService linkService; |
| 45 | 45 | ||
| 46 | + /** | ||
| 47 | + * Result of tunnel creation or removal. | ||
| 48 | + */ | ||
| 46 | public enum Result { | 49 | public enum Result { |
| 50 | + /** | ||
| 51 | + * Success. | ||
| 52 | + */ | ||
| 47 | SUCCESS, | 53 | SUCCESS, |
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * More than one router needs to specified to created a tunnel. | ||
| 57 | + */ | ||
| 48 | WRONG_PATH, | 58 | WRONG_PATH, |
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * The same tunnel exists already. | ||
| 62 | + */ | ||
| 49 | TUNNEL_EXISTS, | 63 | TUNNEL_EXISTS, |
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * The same tunnel ID exists already. | ||
| 67 | + */ | ||
| 50 | ID_EXISTS, | 68 | ID_EXISTS, |
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * Tunnel not found. | ||
| 72 | + */ | ||
| 51 | TUNNEL_NOT_FOUND, | 73 | TUNNEL_NOT_FOUND, |
| 74 | + | ||
| 75 | + /** | ||
| 76 | + * Cannot remove the tunnel used by a policy. | ||
| 77 | + */ | ||
| 52 | TUNNEL_IN_USE, | 78 | TUNNEL_IN_USE, |
| 79 | + | ||
| 80 | + /** | ||
| 81 | + * Failed to create/remove groups for the tunnel. | ||
| 82 | + */ | ||
| 53 | INTERNAL_ERROR | 83 | INTERNAL_ERROR |
| 54 | } | 84 | } |
| 55 | 85 | ||
| 86 | + /** | ||
| 87 | + * Constructs tunnel handler. | ||
| 88 | + * | ||
| 89 | + * @param linkService link service | ||
| 90 | + * @param deviceConfiguration device configuration | ||
| 91 | + * @param groupHandlerMap group handler map | ||
| 92 | + * @param tunnelStore tunnel store | ||
| 93 | + */ | ||
| 56 | public TunnelHandler(LinkService linkService, | 94 | public TunnelHandler(LinkService linkService, |
| 57 | DeviceConfiguration deviceConfiguration, | 95 | DeviceConfiguration deviceConfiguration, |
| 58 | Map<DeviceId, DefaultGroupHandler> groupHandlerMap, | 96 | Map<DeviceId, DefaultGroupHandler> groupHandlerMap, | ... | ... |
| ... | @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableSet; | ... | @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableSet; |
| 19 | import org.onlab.packet.Ip4Address; | 19 | import org.onlab.packet.Ip4Address; |
| 20 | import org.onlab.packet.Ip4Prefix; | 20 | import org.onlab.packet.Ip4Prefix; |
| 21 | import org.onlab.packet.MacAddress; | 21 | import org.onlab.packet.MacAddress; |
| 22 | +import org.onlab.packet.VlanId; | ||
| 22 | import org.onosproject.incubator.net.config.basics.ConfigException; | 23 | import org.onosproject.incubator.net.config.basics.ConfigException; |
| 23 | import org.onosproject.incubator.net.config.basics.InterfaceConfig; | 24 | import org.onosproject.incubator.net.config.basics.InterfaceConfig; |
| 24 | import org.onosproject.incubator.net.intf.Interface; | 25 | import org.onosproject.incubator.net.intf.Interface; |
| ... | @@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory; | ... | @@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory; |
| 33 | import java.util.ArrayList; | 34 | import java.util.ArrayList; |
| 34 | import java.util.HashMap; | 35 | import java.util.HashMap; |
| 35 | import java.util.HashSet; | 36 | import java.util.HashSet; |
| 37 | +import java.util.LinkedList; | ||
| 36 | import java.util.List; | 38 | import java.util.List; |
| 37 | import java.util.Map; | 39 | import java.util.Map; |
| 38 | import java.util.Set; | 40 | import java.util.Set; |
| ... | @@ -48,8 +50,8 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -48,8 +50,8 @@ public class DeviceConfiguration implements DeviceProperties { |
| 48 | private static final Logger log = LoggerFactory | 50 | private static final Logger log = LoggerFactory |
| 49 | .getLogger(DeviceConfiguration.class); | 51 | .getLogger(DeviceConfiguration.class); |
| 50 | private final List<Integer> allSegmentIds = new ArrayList<>(); | 52 | private final List<Integer> allSegmentIds = new ArrayList<>(); |
| 51 | - private final ConcurrentHashMap<DeviceId, SegmentRouterInfo> deviceConfigMap | 53 | + private final Map<DeviceId, SegmentRouterInfo> deviceConfigMap = new ConcurrentHashMap<>(); |
| 52 | - = new ConcurrentHashMap<>(); | 54 | + private final Map<VlanId, List<ConnectPoint>> xConnects = new ConcurrentHashMap<>(); |
| 53 | 55 | ||
| 54 | private class SegmentRouterInfo { | 56 | private class SegmentRouterInfo { |
| 55 | int nodeSid; | 57 | int nodeSid; |
| ... | @@ -62,14 +64,14 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -62,14 +64,14 @@ public class DeviceConfiguration implements DeviceProperties { |
| 62 | Map<Integer, Set<Integer>> adjacencySids; | 64 | Map<Integer, Set<Integer>> adjacencySids; |
| 63 | 65 | ||
| 64 | public SegmentRouterInfo() { | 66 | public SegmentRouterInfo() { |
| 65 | - this.gatewayIps = new HashMap<>(); | 67 | + gatewayIps = new HashMap<>(); |
| 66 | - this.subnets = new HashMap<>(); | 68 | + subnets = new HashMap<>(); |
| 67 | } | 69 | } |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | /** | 72 | /** |
| 71 | - * Constructor. Reads all the configuration for all devices of type | 73 | + * Constructs device configuration for all Segment Router devices, |
| 72 | - * Segment Router and organizes into various maps for easier access. | 74 | + * organizing the data into various maps for easier access. |
| 73 | * | 75 | * |
| 74 | * @param cfgService config service | 76 | * @param cfgService config service |
| 75 | */ | 77 | */ |
| ... | @@ -88,8 +90,8 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -88,8 +90,8 @@ public class DeviceConfiguration implements DeviceProperties { |
| 88 | info.isEdge = config.isEdgeRouter(); | 90 | info.isEdge = config.isEdgeRouter(); |
| 89 | info.adjacencySids = config.adjacencySids(); | 91 | info.adjacencySids = config.adjacencySids(); |
| 90 | 92 | ||
| 91 | - this.deviceConfigMap.put(info.deviceId, info); | 93 | + deviceConfigMap.put(info.deviceId, info); |
| 92 | - this.allSegmentIds.add(info.nodeSid); | 94 | + allSegmentIds.add(info.nodeSid); |
| 93 | }); | 95 | }); |
| 94 | 96 | ||
| 95 | // Read gatewayIps and subnets from port subject. | 97 | // Read gatewayIps and subnets from port subject. |
| ... | @@ -106,17 +108,42 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -106,17 +108,42 @@ public class DeviceConfiguration implements DeviceProperties { |
| 106 | return; | 108 | return; |
| 107 | } | 109 | } |
| 108 | networkInterfaces.forEach(networkInterface -> { | 110 | networkInterfaces.forEach(networkInterface -> { |
| 109 | - DeviceId dpid = networkInterface.connectPoint().deviceId(); | 111 | + VlanId vlanId = networkInterface.vlan(); |
| 110 | - PortNumber port = networkInterface.connectPoint().port(); | 112 | + ConnectPoint connectPoint = networkInterface.connectPoint(); |
| 111 | - SegmentRouterInfo info = this.deviceConfigMap.get(dpid); | 113 | + DeviceId dpid = connectPoint.deviceId(); |
| 114 | + PortNumber port = connectPoint.port(); | ||
| 115 | + SegmentRouterInfo info = deviceConfigMap.get(dpid); | ||
| 112 | 116 | ||
| 113 | // skip if there is no corresponding device for this ConenctPoint | 117 | // skip if there is no corresponding device for this ConenctPoint |
| 114 | if (info != null) { | 118 | if (info != null) { |
| 119 | + // Extract subnet information | ||
| 115 | Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses(); | 120 | Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses(); |
| 116 | interfaceAddresses.forEach(interfaceAddress -> { | 121 | interfaceAddresses.forEach(interfaceAddress -> { |
| 117 | info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); | 122 | info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); |
| 118 | info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); | 123 | info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); |
| 119 | }); | 124 | }); |
| 125 | + | ||
| 126 | + // Extract VLAN cross-connect information | ||
| 127 | + // Do not setup cross-connect if VLAN is NONE | ||
| 128 | + if (vlanId.equals(VlanId.NONE)) { | ||
| 129 | + return; | ||
| 130 | + } | ||
| 131 | + List<ConnectPoint> connectPoints = xConnects.get(vlanId); | ||
| 132 | + if (connectPoints != null) { | ||
| 133 | + if (connectPoints.size() != 1) { | ||
| 134 | + log.warn("Cross-connect should only have two endpoints. Aborting."); | ||
| 135 | + return; | ||
| 136 | + } | ||
| 137 | + if (!connectPoints.get(0).deviceId().equals(connectPoint.deviceId())) { | ||
| 138 | + log.warn("Cross-connect endpoints must be on the same switch. Aborting."); | ||
| 139 | + return; | ||
| 140 | + } | ||
| 141 | + connectPoints.add(connectPoint); | ||
| 142 | + } else { | ||
| 143 | + connectPoints = new LinkedList<>(); | ||
| 144 | + connectPoints.add(connectPoint); | ||
| 145 | + xConnects.put(vlanId, connectPoints); | ||
| 146 | + } | ||
| 120 | } | 147 | } |
| 121 | }); | 148 | }); |
| 122 | 149 | ||
| ... | @@ -235,6 +262,11 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -235,6 +262,11 @@ public class DeviceConfiguration implements DeviceProperties { |
| 235 | return subnetPortMap; | 262 | return subnetPortMap; |
| 236 | } | 263 | } |
| 237 | 264 | ||
| 265 | + @Override | ||
| 266 | + public Map<VlanId, List<ConnectPoint>> getXConnects() { | ||
| 267 | + return xConnects; | ||
| 268 | + } | ||
| 269 | + | ||
| 238 | /** | 270 | /** |
| 239 | * Returns the device identifier or data plane identifier (dpid) | 271 | * Returns the device identifier or data plane identifier (dpid) |
| 240 | * of a segment router given its segment id. | 272 | * of a segment router given its segment id. | ... | ... |
| ... | @@ -21,6 +21,8 @@ import java.util.Map; | ... | @@ -21,6 +21,8 @@ import java.util.Map; |
| 21 | import org.onlab.packet.Ip4Address; | 21 | import org.onlab.packet.Ip4Address; |
| 22 | import org.onlab.packet.Ip4Prefix; | 22 | import org.onlab.packet.Ip4Prefix; |
| 23 | import org.onlab.packet.MacAddress; | 23 | import org.onlab.packet.MacAddress; |
| 24 | +import org.onlab.packet.VlanId; | ||
| 25 | +import org.onosproject.net.ConnectPoint; | ||
| 24 | import org.onosproject.net.DeviceId; | 26 | import org.onosproject.net.DeviceId; |
| 25 | import org.onosproject.net.PortNumber; | 27 | import org.onosproject.net.PortNumber; |
| 26 | 28 | ||
| ... | @@ -93,4 +95,11 @@ public interface DeviceProperties { | ... | @@ -93,4 +95,11 @@ public interface DeviceProperties { |
| 93 | * @return a map that contains all subnet-to-ports mapping of given device | 95 | * @return a map that contains all subnet-to-ports mapping of given device |
| 94 | */ | 96 | */ |
| 95 | Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId); | 97 | Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId); |
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * Returns the VLAN cross-connect configuration. | ||
| 101 | + * | ||
| 102 | + * @return A map of that maps VLAN ID to a list of cross-connect endpoints | ||
| 103 | + */ | ||
| 104 | + Map<VlanId, List<ConnectPoint>> getXConnects(); | ||
| 96 | } | 105 | } | ... | ... |
| ... | @@ -35,24 +35,24 @@ import java.util.Set; | ... | @@ -35,24 +35,24 @@ import java.util.Set; |
| 35 | * Configuration object for Segment Routing Application. | 35 | * Configuration object for Segment Routing Application. |
| 36 | */ | 36 | */ |
| 37 | public class SegmentRoutingConfig extends Config<DeviceId> { | 37 | public class SegmentRoutingConfig extends Config<DeviceId> { |
| 38 | - public static final String NAME = "name"; | 38 | + private static final String NAME = "name"; |
| 39 | - public static final String IP = "routerIp"; | 39 | + private static final String IP = "routerIp"; |
| 40 | - public static final String MAC = "routerMac"; | 40 | + private static final String MAC = "routerMac"; |
| 41 | - public static final String SID = "nodeSid"; | 41 | + private static final String SID = "nodeSid"; |
| 42 | - public static final String EDGE = "isEdgeRouter"; | 42 | + private static final String EDGE = "isEdgeRouter"; |
| 43 | - public static final String ADJSIDS = "adjacencySids"; | 43 | + private static final String ADJSIDS = "adjacencySids"; |
| 44 | - public static final String ADJSID = "adjSid"; | 44 | + private static final String ADJSID = "adjSid"; |
| 45 | - public static final String PORTS = "ports"; | 45 | + private static final String PORTS = "ports"; |
| 46 | 46 | ||
| 47 | @Override | 47 | @Override |
| 48 | public boolean isValid() { | 48 | public boolean isValid() { |
| 49 | return hasOnlyFields(NAME, IP, MAC, SID, EDGE, ADJSIDS, ADJSID, PORTS) && | 49 | return hasOnlyFields(NAME, IP, MAC, SID, EDGE, ADJSIDS, ADJSID, PORTS) && |
| 50 | - this.name() != null && | 50 | + name() != null && |
| 51 | - this.routerIp() != null && | 51 | + routerIp() != null && |
| 52 | - this.routerMac() != null && | 52 | + routerMac() != null && |
| 53 | - this.nodeSid() != -1 && | 53 | + nodeSid() != -1 && |
| 54 | - this.isEdgeRouter() != null && | 54 | + isEdgeRouter() != null && |
| 55 | - this.adjacencySids() != null; | 55 | + adjacencySids() != null; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | /** | 58 | /** | ... | ... |
| ... | @@ -26,7 +26,6 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; | ... | @@ -26,7 +26,6 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; |
| 26 | import org.onosproject.net.link.LinkService; | 26 | import org.onosproject.net.link.LinkService; |
| 27 | import org.onosproject.segmentrouting.SegmentRoutingManager; | 27 | import org.onosproject.segmentrouting.SegmentRoutingManager; |
| 28 | import org.onosproject.segmentrouting.config.DeviceProperties; | 28 | import org.onosproject.segmentrouting.config.DeviceProperties; |
| 29 | -import org.onosproject.store.service.EventuallyConsistentMap; | ||
| 30 | 29 | ||
| 31 | /** | 30 | /** |
| 32 | * Default ECMP group handler creation module for an edge device. | 31 | * Default ECMP group handler creation module for an edge device. |
| ... | @@ -47,22 +46,13 @@ import org.onosproject.store.service.EventuallyConsistentMap; | ... | @@ -47,22 +46,13 @@ import org.onosproject.store.service.EventuallyConsistentMap; |
| 47 | * 8) what about ecmp no label case | 46 | * 8) what about ecmp no label case |
| 48 | */ | 47 | */ |
| 49 | public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | 48 | public class DefaultEdgeGroupHandler extends DefaultGroupHandler { |
| 50 | - // TODO Access stores through srManager | ||
| 51 | protected DefaultEdgeGroupHandler(DeviceId deviceId, | 49 | protected DefaultEdgeGroupHandler(DeviceId deviceId, |
| 52 | ApplicationId appId, | 50 | ApplicationId appId, |
| 53 | DeviceProperties config, | 51 | DeviceProperties config, |
| 54 | LinkService linkService, | 52 | LinkService linkService, |
| 55 | FlowObjectiveService flowObjService, | 53 | FlowObjectiveService flowObjService, |
| 56 | - EventuallyConsistentMap< | ||
| 57 | - NeighborSetNextObjectiveStoreKey, | ||
| 58 | - Integer> nsNextObjStore, | ||
| 59 | - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, | ||
| 60 | - Integer> subnetNextObjStore, | ||
| 61 | - EventuallyConsistentMap<PortNextObjectiveStoreKey, | ||
| 62 | - Integer> portNextObjStore, | ||
| 63 | SegmentRoutingManager srManager) { | 54 | SegmentRoutingManager srManager) { |
| 64 | - super(deviceId, appId, config, linkService, flowObjService, | 55 | + super(deviceId, appId, config, linkService, flowObjService, srManager); |
| 65 | - nsNextObjStore, subnetNextObjStore, portNextObjStore, srManager); | ||
| 66 | } | 56 | } |
| 67 | 57 | ||
| 68 | @Override | 58 | @Override | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -26,7 +26,6 @@ import org.onosproject.net.link.LinkService; | ... | @@ -26,7 +26,6 @@ import org.onosproject.net.link.LinkService; |
| 26 | import org.onosproject.segmentrouting.SegmentRoutingManager; | 26 | import org.onosproject.segmentrouting.SegmentRoutingManager; |
| 27 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; | 27 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; |
| 28 | import org.onosproject.segmentrouting.config.DeviceProperties; | 28 | import org.onosproject.segmentrouting.config.DeviceProperties; |
| 29 | -import org.onosproject.store.service.EventuallyConsistentMap; | ||
| 30 | 29 | ||
| 31 | /** | 30 | /** |
| 32 | * Default ECMP group handler creation module for a transit device. | 31 | * Default ECMP group handler creation module for a transit device. |
| ... | @@ -41,22 +40,13 @@ import org.onosproject.store.service.EventuallyConsistentMap; | ... | @@ -41,22 +40,13 @@ import org.onosproject.store.service.EventuallyConsistentMap; |
| 41 | * 2) all ports to D3 + with no label push, | 40 | * 2) all ports to D3 + with no label push, |
| 42 | */ | 41 | */ |
| 43 | public class DefaultTransitGroupHandler extends DefaultGroupHandler { | 42 | public class DefaultTransitGroupHandler extends DefaultGroupHandler { |
| 44 | - // TODO Access stores through srManager | ||
| 45 | protected DefaultTransitGroupHandler(DeviceId deviceId, | 43 | protected DefaultTransitGroupHandler(DeviceId deviceId, |
| 46 | ApplicationId appId, | 44 | ApplicationId appId, |
| 47 | DeviceProperties config, | 45 | DeviceProperties config, |
| 48 | LinkService linkService, | 46 | LinkService linkService, |
| 49 | FlowObjectiveService flowObjService, | 47 | FlowObjectiveService flowObjService, |
| 50 | - EventuallyConsistentMap< | ||
| 51 | - NeighborSetNextObjectiveStoreKey, | ||
| 52 | - Integer> nsNextObjStore, | ||
| 53 | - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, | ||
| 54 | - Integer> subnetNextObjStore, | ||
| 55 | - EventuallyConsistentMap<PortNextObjectiveStoreKey, | ||
| 56 | - Integer> portNextObjStore, | ||
| 57 | SegmentRoutingManager srManager) { | 48 | SegmentRoutingManager srManager) { |
| 58 | - super(deviceId, appId, config, linkService, flowObjService, | 49 | + super(deviceId, appId, config, linkService, flowObjService, srManager); |
| 59 | - nsNextObjStore, subnetNextObjStore, portNextObjStore, srManager); | ||
| 60 | } | 50 | } |
| 61 | 51 | ||
| 62 | @Override | 52 | @Override | ... | ... |
| ... | @@ -21,22 +21,38 @@ import java.util.Objects; | ... | @@ -21,22 +21,38 @@ import java.util.Objects; |
| 21 | import org.onosproject.net.DeviceId; | 21 | import org.onosproject.net.DeviceId; |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | - * Class definition of Key for Neighborset to NextObjective store. | 24 | + * Key of Neighborset next objective store. |
| 25 | */ | 25 | */ |
| 26 | public class NeighborSetNextObjectiveStoreKey { | 26 | public class NeighborSetNextObjectiveStoreKey { |
| 27 | private final DeviceId deviceId; | 27 | private final DeviceId deviceId; |
| 28 | private final NeighborSet ns; | 28 | private final NeighborSet ns; |
| 29 | 29 | ||
| 30 | + /** | ||
| 31 | + * Constructs the key of neighbor set next objective store. | ||
| 32 | + * | ||
| 33 | + * @param deviceId device ID | ||
| 34 | + * @param ns neighbor set | ||
| 35 | + */ | ||
| 30 | public NeighborSetNextObjectiveStoreKey(DeviceId deviceId, | 36 | public NeighborSetNextObjectiveStoreKey(DeviceId deviceId, |
| 31 | NeighborSet ns) { | 37 | NeighborSet ns) { |
| 32 | this.deviceId = deviceId; | 38 | this.deviceId = deviceId; |
| 33 | this.ns = ns; | 39 | this.ns = ns; |
| 34 | } | 40 | } |
| 35 | 41 | ||
| 42 | + /** | ||
| 43 | + * Returns the device ID in the key. | ||
| 44 | + * | ||
| 45 | + * @return device ID | ||
| 46 | + */ | ||
| 36 | public DeviceId deviceId() { | 47 | public DeviceId deviceId() { |
| 37 | return this.deviceId; | 48 | return this.deviceId; |
| 38 | } | 49 | } |
| 39 | 50 | ||
| 51 | + /** | ||
| 52 | + * Returns the neighbor set in the key. | ||
| 53 | + * | ||
| 54 | + * @return neighbor set | ||
| 55 | + */ | ||
| 40 | public NeighborSet neighborSet() { | 56 | public NeighborSet neighborSet() { |
| 41 | return this.ns; | 57 | return this.ns; |
| 42 | } | 58 | } | ... | ... |
| ... | @@ -31,7 +31,6 @@ import org.onosproject.segmentrouting.SegmentRoutingManager; | ... | @@ -31,7 +31,6 @@ import org.onosproject.segmentrouting.SegmentRoutingManager; |
| 31 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; | 31 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; |
| 32 | import org.onosproject.segmentrouting.config.DeviceProperties; | 32 | import org.onosproject.segmentrouting.config.DeviceProperties; |
| 33 | import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; | 33 | import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; |
| 34 | -import org.onosproject.store.service.EventuallyConsistentMap; | ||
| 35 | import org.onosproject.net.DeviceId; | 34 | import org.onosproject.net.DeviceId; |
| 36 | import org.onosproject.net.PortNumber; | 35 | import org.onosproject.net.PortNumber; |
| 37 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 36 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| ... | @@ -51,33 +50,31 @@ public class PolicyGroupHandler extends DefaultGroupHandler { | ... | @@ -51,33 +50,31 @@ public class PolicyGroupHandler extends DefaultGroupHandler { |
| 51 | private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups = new HashMap<>(); | 50 | private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups = new HashMap<>(); |
| 52 | 51 | ||
| 53 | /** | 52 | /** |
| 54 | - * Policy group handler constructor. | 53 | + * Constructs policy group handler. |
| 55 | * | 54 | * |
| 56 | * @param deviceId device identifier | 55 | * @param deviceId device identifier |
| 57 | * @param appId application identifier | 56 | * @param appId application identifier |
| 58 | * @param config interface to retrieve the device properties | 57 | * @param config interface to retrieve the device properties |
| 59 | * @param linkService link service object | 58 | * @param linkService link service object |
| 60 | * @param flowObjService flow objective service object | 59 | * @param flowObjService flow objective service object |
| 61 | - * @param nsNextObjStore NeighborSet next objective store map | 60 | + * @param srManager segment routing manager |
| 62 | - * @param subnetNextObjStore subnet next objective store map | ||
| 63 | */ | 61 | */ |
| 64 | - // TODO Access stores through srManager | ||
| 65 | public PolicyGroupHandler(DeviceId deviceId, | 62 | public PolicyGroupHandler(DeviceId deviceId, |
| 66 | ApplicationId appId, | 63 | ApplicationId appId, |
| 67 | DeviceProperties config, | 64 | DeviceProperties config, |
| 68 | LinkService linkService, | 65 | LinkService linkService, |
| 69 | FlowObjectiveService flowObjService, | 66 | FlowObjectiveService flowObjService, |
| 70 | - EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, | ||
| 71 | - Integer> nsNextObjStore, | ||
| 72 | - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, | ||
| 73 | - Integer> subnetNextObjStore, | ||
| 74 | - EventuallyConsistentMap<PortNextObjectiveStoreKey, | ||
| 75 | - Integer> portNextObjStore, | ||
| 76 | SegmentRoutingManager srManager) { | 67 | SegmentRoutingManager srManager) { |
| 77 | - super(deviceId, appId, config, linkService, flowObjService, | 68 | + super(deviceId, appId, config, linkService, flowObjService, srManager); |
| 78 | - nsNextObjStore, subnetNextObjStore, portNextObjStore, srManager); | ||
| 79 | } | 69 | } |
| 80 | 70 | ||
| 71 | + /** | ||
| 72 | + * Creates policy group chain. | ||
| 73 | + * | ||
| 74 | + * @param id unique identifier associated with the policy group | ||
| 75 | + * @param params a list of policy group params | ||
| 76 | + * @return policy group identifier | ||
| 77 | + */ | ||
| 81 | public PolicyGroupIdentifier createPolicyGroupChain(String id, | 78 | public PolicyGroupIdentifier createPolicyGroupChain(String id, |
| 82 | List<PolicyGroupParams> params) { | 79 | List<PolicyGroupParams> params) { |
| 83 | List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); | 80 | List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); |
| ... | @@ -222,69 +219,18 @@ public class PolicyGroupHandler extends DefaultGroupHandler { | ... | @@ -222,69 +219,18 @@ public class PolicyGroupHandler extends DefaultGroupHandler { |
| 222 | } | 219 | } |
| 223 | 220 | ||
| 224 | //TODO: Use nextObjective APIs to handle the group chains | 221 | //TODO: Use nextObjective APIs to handle the group chains |
| 225 | - /*@Override | 222 | + /* |
| 226 | - protected void handleGroupEvent(GroupEvent event) { | 223 | + @Override |
| 227 | - if (event.type() == GroupEvent.Type.GROUP_ADDED) { | 224 | + protected void handleGroupEvent(GroupEvent event) {} |
| 228 | - if (dependentGroups.get(event.subject().appCookie()) != null) { | 225 | + */ |
| 229 | - PolicyGroupIdentifier dependentGroupKey = dependentGroups.get(event.subject().appCookie()); | ||
| 230 | - dependentGroups.remove(event.subject().appCookie()); | ||
| 231 | - boolean fullyResolved = true; | ||
| 232 | - for (GroupBucketIdentifier bucketId: | ||
| 233 | - dependentGroupKey.bucketIds()) { | ||
| 234 | - if (bucketId.type() != BucketOutputType.GROUP) { | ||
| 235 | - continue; | ||
| 236 | - } | ||
| 237 | - if (dependentGroups.containsKey(bucketId.outGroup())) { | ||
| 238 | - fullyResolved = false; | ||
| 239 | - break; | ||
| 240 | - } | ||
| 241 | - } | ||
| 242 | - | ||
| 243 | - if (fullyResolved) { | ||
| 244 | - List<GroupBucket> outBuckets = new ArrayList<GroupBucket>(); | ||
| 245 | - for (GroupBucketIdentifier bucketId: | ||
| 246 | - dependentGroupKey.bucketIds()) { | ||
| 247 | - TrafficTreatment.Builder tBuilder = | ||
| 248 | - DefaultTrafficTreatment.builder(); | ||
| 249 | - if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) { | ||
| 250 | - tBuilder.pushMpls() | ||
| 251 | - .setMpls(MplsLabel. | ||
| 252 | - mplsLabel(bucketId.label())); | ||
| 253 | - } | ||
| 254 | - //TODO: BoS | ||
| 255 | - if (bucketId.type() == BucketOutputType.PORT) { | ||
| 256 | - DeviceId neighbor = portDeviceMap. | ||
| 257 | - get(bucketId.outPort()); | ||
| 258 | - tBuilder.setOutput(bucketId.outPort()) | ||
| 259 | - .setEthDst(deviceConfig. | ||
| 260 | - getDeviceMac(neighbor)) | ||
| 261 | - .setEthSrc(nodeMacAddr); | ||
| 262 | - } else { | ||
| 263 | - if (groupService. | ||
| 264 | - getGroup(deviceId, | ||
| 265 | - getGroupKey(bucketId. | ||
| 266 | - outGroup())) == null) { | ||
| 267 | - throw new IllegalStateException(); | ||
| 268 | - } | ||
| 269 | - GroupId indirectGroupId = groupService. | ||
| 270 | - getGroup(deviceId, | ||
| 271 | - getGroupKey(bucketId. | ||
| 272 | - outGroup())).id(); | ||
| 273 | - tBuilder.group(indirectGroupId); | ||
| 274 | - } | ||
| 275 | - outBuckets.add(DefaultGroupBucket. | ||
| 276 | - createSelectGroupBucket(tBuilder.build())); | ||
| 277 | - } | ||
| 278 | - GroupDescription desc = new | ||
| 279 | - DefaultGroupDescription(deviceId, | ||
| 280 | - GroupDescription.Type.SELECT, | ||
| 281 | - new GroupBuckets(outBuckets)); | ||
| 282 | - groupService.addGroup(desc); | ||
| 283 | - } | ||
| 284 | - } | ||
| 285 | - } | ||
| 286 | - }*/ | ||
| 287 | 226 | ||
| 227 | + /** | ||
| 228 | + * Generates policy group key. | ||
| 229 | + * | ||
| 230 | + * @param id unique identifier associated with the policy group | ||
| 231 | + * @param params a list of policy group params | ||
| 232 | + * @return policy group identifier | ||
| 233 | + */ | ||
| 288 | public PolicyGroupIdentifier generatePolicyGroupKey(String id, | 234 | public PolicyGroupIdentifier generatePolicyGroupKey(String id, |
| 289 | List<PolicyGroupParams> params) { | 235 | List<PolicyGroupParams> params) { |
| 290 | List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); | 236 | List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); |
| ... | @@ -354,6 +300,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { | ... | @@ -354,6 +300,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { |
| 354 | return innermostGroupkey; | 300 | return innermostGroupkey; |
| 355 | } | 301 | } |
| 356 | 302 | ||
| 303 | + /** | ||
| 304 | + * Removes policy group chain. | ||
| 305 | + * | ||
| 306 | + * @param key policy group identifier | ||
| 307 | + */ | ||
| 357 | public void removeGroupChain(PolicyGroupIdentifier key) { | 308 | public void removeGroupChain(PolicyGroupIdentifier key) { |
| 358 | checkArgument(key != null); | 309 | checkArgument(key != null); |
| 359 | List<PolicyGroupIdentifier> groupsToBeDeleted = new ArrayList<>(); | 310 | List<PolicyGroupIdentifier> groupsToBeDeleted = new ArrayList<>(); | ... | ... |
| ... | @@ -28,7 +28,7 @@ public class PolicyGroupIdentifier { | ... | @@ -28,7 +28,7 @@ public class PolicyGroupIdentifier { |
| 28 | private List<GroupBucketIdentifier> bucketIds; | 28 | private List<GroupBucketIdentifier> bucketIds; |
| 29 | 29 | ||
| 30 | /** | 30 | /** |
| 31 | - * Constructor. | 31 | + * Constructs policy group identifier. |
| 32 | * | 32 | * |
| 33 | * @param id unique identifier associated with the policy group | 33 | * @param id unique identifier associated with the policy group |
| 34 | * @param input policy group params associated with this group | 34 | * @param input policy group params associated with this group | ... | ... |
| ... | @@ -7,15 +7,23 @@ import org.onosproject.net.flow.TrafficTreatment; | ... | @@ -7,15 +7,23 @@ import org.onosproject.net.flow.TrafficTreatment; |
| 7 | import java.util.Objects; | 7 | import java.util.Objects; |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | - * Class definition of Key for Device/Port to NextObjective store. Since there | 10 | + * Key of Device/Port to NextObjective store. |
| 11 | - * can be multiple next objectives to the same physical port, we differentiate | 11 | + * |
| 12 | - * between them by including the treatment in the key. | 12 | + * Since there can be multiple next objectives to the same physical port, |
| 13 | + * we differentiate between them by including the treatment in the key. | ||
| 13 | */ | 14 | */ |
| 14 | public class PortNextObjectiveStoreKey { | 15 | public class PortNextObjectiveStoreKey { |
| 15 | private final DeviceId deviceId; | 16 | private final DeviceId deviceId; |
| 16 | private final PortNumber portNum; | 17 | private final PortNumber portNum; |
| 17 | private final TrafficTreatment treatment; | 18 | private final TrafficTreatment treatment; |
| 18 | 19 | ||
| 20 | + /** | ||
| 21 | + * Constructs the key of port next objective store. | ||
| 22 | + * | ||
| 23 | + * @param deviceId device ID | ||
| 24 | + * @param portNum port number | ||
| 25 | + * @param treatment treatment that will be applied to the interface | ||
| 26 | + */ | ||
| 19 | public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum, | 27 | public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum, |
| 20 | TrafficTreatment treatment) { | 28 | TrafficTreatment treatment) { |
| 21 | this.deviceId = deviceId; | 29 | this.deviceId = deviceId; | ... | ... |
| ... | @@ -22,12 +22,18 @@ import org.onosproject.net.DeviceId; | ... | @@ -22,12 +22,18 @@ import org.onosproject.net.DeviceId; |
| 22 | import java.util.Objects; | 22 | import java.util.Objects; |
| 23 | 23 | ||
| 24 | /** | 24 | /** |
| 25 | - * Class definition of Key for Subnet to NextObjective store. | 25 | + * Key of Subnet to NextObjective store. |
| 26 | */ | 26 | */ |
| 27 | public class SubnetNextObjectiveStoreKey { | 27 | public class SubnetNextObjectiveStoreKey { |
| 28 | private final DeviceId deviceId; | 28 | private final DeviceId deviceId; |
| 29 | private final IpPrefix prefix; | 29 | private final IpPrefix prefix; |
| 30 | 30 | ||
| 31 | + /** | ||
| 32 | + * Constructs the key of subnet next objective store. | ||
| 33 | + * | ||
| 34 | + * @param deviceId device ID | ||
| 35 | + * @param prefix subnet information | ||
| 36 | + */ | ||
| 31 | public SubnetNextObjectiveStoreKey(DeviceId deviceId, | 37 | public SubnetNextObjectiveStoreKey(DeviceId deviceId, |
| 32 | IpPrefix prefix) { | 38 | IpPrefix prefix) { |
| 33 | this.deviceId = deviceId; | 39 | this.deviceId = deviceId; | ... | ... |
| 1 | +/* | ||
| 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 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.segmentrouting.grouphandler; | ||
| 18 | + | ||
| 19 | +import org.onlab.packet.VlanId; | ||
| 20 | +import org.onosproject.net.DeviceId; | ||
| 21 | + | ||
| 22 | +import java.util.Objects; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * Key of VLAN cross-connect next objective store. | ||
| 26 | + */ | ||
| 27 | +public class XConnectNextObjectiveStoreKey { | ||
| 28 | + private final DeviceId deviceId; | ||
| 29 | + private final VlanId vlanId; | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * Constructs the key of cross-connect next objective store. | ||
| 33 | + * | ||
| 34 | + * @param deviceId device ID of the VLAN cross-connection | ||
| 35 | + * @param vlanId VLAN ID of the VLAN cross-connection | ||
| 36 | + */ | ||
| 37 | + public XConnectNextObjectiveStoreKey(DeviceId deviceId, VlanId vlanId) { | ||
| 38 | + this.deviceId = deviceId; | ||
| 39 | + this.vlanId = vlanId; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * Returns the device ID of this key. | ||
| 44 | + * | ||
| 45 | + * @return device ID | ||
| 46 | + */ | ||
| 47 | + public DeviceId deviceId() { | ||
| 48 | + return this.deviceId; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Returns the VLAN ID of this key. | ||
| 53 | + * | ||
| 54 | + * @return VLAN ID | ||
| 55 | + */ | ||
| 56 | + public VlanId vlanId() { | ||
| 57 | + return this.vlanId; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public boolean equals(Object o) { | ||
| 62 | + if (this == o) { | ||
| 63 | + return true; | ||
| 64 | + } | ||
| 65 | + if (!(o instanceof XConnectNextObjectiveStoreKey)) { | ||
| 66 | + return false; | ||
| 67 | + } | ||
| 68 | + XConnectNextObjectiveStoreKey that = | ||
| 69 | + (XConnectNextObjectiveStoreKey) o; | ||
| 70 | + return (Objects.equals(this.deviceId, that.deviceId) && | ||
| 71 | + Objects.equals(this.vlanId, that.vlanId)); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + // The list of neighbor ids and label are used for comparison. | ||
| 75 | + @Override | ||
| 76 | + public int hashCode() { | ||
| 77 | + return Objects.hash(deviceId, vlanId); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + @Override | ||
| 81 | + public String toString() { | ||
| 82 | + return "Device: " + deviceId + " VlanId: " + vlanId; | ||
| 83 | + } | ||
| 84 | +} |
| ... | @@ -21,6 +21,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; | ... | @@ -21,6 +21,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; |
| 21 | import org.onosproject.segmentrouting.Policy; | 21 | import org.onosproject.segmentrouting.Policy; |
| 22 | import org.onosproject.segmentrouting.TunnelPolicy; | 22 | import org.onosproject.segmentrouting.TunnelPolicy; |
| 23 | 23 | ||
| 24 | +/** | ||
| 25 | + * Codec of Policy class. | ||
| 26 | + */ | ||
| 24 | public final class PolicyCodec extends JsonCodec<Policy> { | 27 | public final class PolicyCodec extends JsonCodec<Policy> { |
| 25 | 28 | ||
| 26 | // JSON field names | 29 | // JSON field names | ... | ... |
| ... | @@ -26,6 +26,9 @@ import org.onosproject.segmentrouting.Tunnel; | ... | @@ -26,6 +26,9 @@ import org.onosproject.segmentrouting.Tunnel; |
| 26 | import java.util.ArrayList; | 26 | import java.util.ArrayList; |
| 27 | import java.util.List; | 27 | import java.util.List; |
| 28 | 28 | ||
| 29 | +/** | ||
| 30 | + * Codec of Tunnel class. | ||
| 31 | + */ | ||
| 29 | public final class TunnelCodec extends JsonCodec<Tunnel> { | 32 | public final class TunnelCodec extends JsonCodec<Tunnel> { |
| 30 | 33 | ||
| 31 | // JSON field names | 34 | // JSON field names | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -305,29 +305,35 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -305,29 +305,35 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | VlanId assignedVlan = null; | 307 | VlanId assignedVlan = null; |
| 308 | - if (vidCriterion != null && vidCriterion.vlanId() == VlanId.NONE) { | 308 | + // For VLAN cross-connect packets, use the configured VLAN |
| 309 | - // untagged packets are assigned vlans in OF-DPA | 309 | + if (vidCriterion != null) { |
| 310 | - if (filt.meta() == null) { | 310 | + if (vidCriterion.vlanId() != VlanId.NONE) { |
| 311 | - log.error("Missing metadata in filtering objective required " | 311 | + assignedVlan = vidCriterion.vlanId(); |
| 312 | - + "for vlan assignment in dev {}", deviceId); | 312 | + |
| 313 | - fail(filt, ObjectiveError.BADPARAMS); | 313 | + // For untagged packets, assign a VLAN ID |
| 314 | - return; | 314 | + } else { |
| 315 | - } | 315 | + if (filt.meta() == null) { |
| 316 | - for (Instruction i : filt.meta().allInstructions()) { | 316 | + log.error("Missing metadata in filtering objective required " + |
| 317 | - if (i instanceof ModVlanIdInstruction) { | 317 | + "for vlan assignment in dev {}", deviceId); |
| 318 | - assignedVlan = ((ModVlanIdInstruction) i).vlanId(); | 318 | + fail(filt, ObjectiveError.BADPARAMS); |
| 319 | + return; | ||
| 320 | + } | ||
| 321 | + for (Instruction i : filt.meta().allInstructions()) { | ||
| 322 | + if (i instanceof ModVlanIdInstruction) { | ||
| 323 | + assignedVlan = ((ModVlanIdInstruction) i).vlanId(); | ||
| 324 | + } | ||
| 325 | + } | ||
| 326 | + if (assignedVlan == null) { | ||
| 327 | + log.error("Driver requires an assigned vlan-id to tag incoming " | ||
| 328 | + + "untagged packets. Not processing vlan filters on " | ||
| 329 | + + "device {}", deviceId); | ||
| 330 | + fail(filt, ObjectiveError.BADPARAMS); | ||
| 331 | + return; | ||
| 319 | } | 332 | } |
| 320 | - } | ||
| 321 | - if (assignedVlan == null) { | ||
| 322 | - log.error("Driver requires an assigned vlan-id to tag incoming " | ||
| 323 | - + "untagged packets. Not processing vlan filters on " | ||
| 324 | - + "device {}", deviceId); | ||
| 325 | - fail(filt, ObjectiveError.BADPARAMS); | ||
| 326 | - return; | ||
| 327 | } | 333 | } |
| 328 | } | 334 | } |
| 329 | 335 | ||
| 330 | - if (ethCriterion == null) { | 336 | + if (ethCriterion == null || ethCriterion.mac().equals(MacAddress.NONE)) { |
| 331 | log.debug("filtering objective missing dstMac, cannot program TMAC table"); | 337 | log.debug("filtering objective missing dstMac, cannot program TMAC table"); |
| 332 | } else { | 338 | } else { |
| 333 | for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion, | 339 | for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion, |
| ... | @@ -340,8 +346,8 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -340,8 +346,8 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
| 340 | } | 346 | } |
| 341 | 347 | ||
| 342 | if (ethCriterion == null || vidCriterion == null) { | 348 | if (ethCriterion == null || vidCriterion == null) { |
| 343 | - log.debug("filtering objective missing dstMac or vlan, cannot program" | 349 | + log.debug("filtering objective missing dstMac or VLAN, " |
| 344 | - + "Vlan Table"); | 350 | + + "cannot program VLAN Table"); |
| 345 | } else { | 351 | } else { |
| 346 | for (FlowRule vlanRule : processVlanIdFilter(portCriterion, vidCriterion, | 352 | for (FlowRule vlanRule : processVlanIdFilter(portCriterion, vidCriterion, |
| 347 | assignedVlan, | 353 | assignedVlan, | ... | ... |
| ... | @@ -837,7 +837,6 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -837,7 +837,6 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
| 837 | if (vlanIdCriterion.vlanId() != VlanId.NONE) { | 837 | if (vlanIdCriterion.vlanId() != VlanId.NONE) { |
| 838 | selector.matchVlanId(vlanIdCriterion.vlanId()); | 838 | selector.matchVlanId(vlanIdCriterion.vlanId()); |
| 839 | selector.matchInPort(p.port()); | 839 | selector.matchInPort(p.port()); |
| 840 | - treatment.deferred().popVlan(); | ||
| 841 | } else { | 840 | } else { |
| 842 | selector.matchInPort(p.port()); | 841 | selector.matchInPort(p.port()); |
| 843 | treatment.immediate().pushVlan().setVlanId(assignedVlan); | 842 | treatment.immediate().pushVlan().setVlanId(assignedVlan); |
| ... | @@ -887,25 +886,31 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -887,25 +886,31 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
| 887 | } | 886 | } |
| 888 | 887 | ||
| 889 | VlanId assignedVlan = null; | 888 | VlanId assignedVlan = null; |
| 890 | - if (vlanIdCriterion != null && vlanIdCriterion.vlanId() == VlanId.NONE) { | 889 | + if (vlanIdCriterion != null) { |
| 891 | - // Assign a VLAN ID to untagged packets | 890 | + // For VLAN cross-connect packets, use the configured VLAN |
| 892 | - if (filt.meta() == null) { | 891 | + if (vlanIdCriterion.vlanId() != VlanId.NONE) { |
| 893 | - log.error("Missing metadata in filtering objective required " | 892 | + assignedVlan = vlanIdCriterion.vlanId(); |
| 894 | - + "for vlan assignment in dev {}", deviceId); | 893 | + |
| 895 | - fail(filt, ObjectiveError.BADPARAMS); | 894 | + // For untagged packets, assign a VLAN ID |
| 896 | - return; | 895 | + } else { |
| 897 | - } | 896 | + if (filt.meta() == null) { |
| 898 | - for (Instruction i : filt.meta().allInstructions()) { | 897 | + log.error("Missing metadata in filtering objective required " + |
| 899 | - if (i instanceof ModVlanIdInstruction) { | 898 | + "for vlan assignment in dev {}", deviceId); |
| 900 | - assignedVlan = ((ModVlanIdInstruction) i).vlanId(); | 899 | + fail(filt, ObjectiveError.BADPARAMS); |
| 900 | + return; | ||
| 901 | + } | ||
| 902 | + for (Instruction i : filt.meta().allInstructions()) { | ||
| 903 | + if (i instanceof ModVlanIdInstruction) { | ||
| 904 | + assignedVlan = ((ModVlanIdInstruction) i).vlanId(); | ||
| 905 | + } | ||
| 906 | + } | ||
| 907 | + if (assignedVlan == null) { | ||
| 908 | + log.error("Driver requires an assigned vlan-id to tag incoming " | ||
| 909 | + + "untagged packets. Not processing vlan filters on " | ||
| 910 | + + "device {}", deviceId); | ||
| 911 | + fail(filt, ObjectiveError.BADPARAMS); | ||
| 912 | + return; | ||
| 901 | } | 913 | } |
| 902 | - } | ||
| 903 | - if (assignedVlan == null) { | ||
| 904 | - log.error("Driver requires an assigned vlan-id to tag incoming " | ||
| 905 | - + "untagged packets. Not processing vlan filters on " | ||
| 906 | - + "device {}", deviceId); | ||
| 907 | - fail(filt, ObjectiveError.BADPARAMS); | ||
| 908 | - return; | ||
| 909 | } | 914 | } |
| 910 | } | 915 | } |
| 911 | 916 | ||
| ... | @@ -923,9 +928,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -923,9 +928,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
| 923 | } | 928 | } |
| 924 | } | 929 | } |
| 925 | 930 | ||
| 926 | - if (ethCriterion == null || vlanIdCriterion == null) { | 931 | + if (vlanIdCriterion == null) { |
| 927 | - log.debug("filtering objective missing dstMac or vlan, cannot program" | 932 | + log.debug("filtering objective missing VLAN ID criterion, " |
| 928 | - + "Vlan Table"); | 933 | + + "cannot program VLAN Table"); |
| 929 | } else { | 934 | } else { |
| 930 | for (FlowRule vlanRule : processVlanIdFilter(vlanIdCriterion, | 935 | for (FlowRule vlanRule : processVlanIdFilter(vlanIdCriterion, |
| 931 | filt, | 936 | filt, | ... | ... |
| 1 | +{ | ||
| 2 | + "ports" : { | ||
| 3 | + "of:0000000000000001/3" : { | ||
| 4 | + "interfaces" : [ | ||
| 5 | + { | ||
| 6 | + "ips" : [ "10.0.1.254/24" ], | ||
| 7 | + "vlan" : "-1" | ||
| 8 | + }, | ||
| 9 | + { | ||
| 10 | + "vlan" : "100" | ||
| 11 | + } | ||
| 12 | + ] | ||
| 13 | + }, | ||
| 14 | + "of:0000000000000001/4" : { | ||
| 15 | + "interfaces" : [ | ||
| 16 | + { | ||
| 17 | + "ips" : [ "10.0.1.254/24" ], | ||
| 18 | + "vlan" : "-1" | ||
| 19 | + } | ||
| 20 | + ] | ||
| 21 | + }, | ||
| 22 | + "of:0000000000000001/5" : { | ||
| 23 | + "interfaces" : [ | ||
| 24 | + { | ||
| 25 | + "vlan" : "100" | ||
| 26 | + } | ||
| 27 | + ] | ||
| 28 | + }, | ||
| 29 | + "of:0000000000000002/3" : { | ||
| 30 | + "interfaces" : [ | ||
| 31 | + { | ||
| 32 | + "ips" : [ "10.0.2.254/24" ], | ||
| 33 | + "vlan" : "-1" | ||
| 34 | + } | ||
| 35 | + ] | ||
| 36 | + }, | ||
| 37 | + "of:0000000000000002/4" : { | ||
| 38 | + "interfaces" : [ | ||
| 39 | + { | ||
| 40 | + "ips" : [ "10.0.2.254/24" ], | ||
| 41 | + "vlan" : "-1" | ||
| 42 | + } | ||
| 43 | + ] | ||
| 44 | + } | ||
| 45 | + }, | ||
| 46 | + "devices" : { | ||
| 47 | + "of:0000000000000001" : { | ||
| 48 | + "segmentrouting" : { | ||
| 49 | + "name" : "Leaf-R1", | ||
| 50 | + "nodeSid" : 101, | ||
| 51 | + "routerIp" : "10.0.1.254", | ||
| 52 | + "routerMac" : "00:00:00:00:01:80", | ||
| 53 | + "isEdgeRouter" : true, | ||
| 54 | + "adjacencySids" : [] | ||
| 55 | + } | ||
| 56 | + }, | ||
| 57 | + "of:0000000000000002" : { | ||
| 58 | + "segmentrouting" : { | ||
| 59 | + "name" : "Leaf-R2", | ||
| 60 | + "nodeSid" : 102, | ||
| 61 | + "routerIp" : "10.0.2.254", | ||
| 62 | + "routerMac" : "00:00:00:00:02:80", | ||
| 63 | + "isEdgeRouter" : true, | ||
| 64 | + "adjacencySids" : [] | ||
| 65 | + } | ||
| 66 | + }, | ||
| 67 | + "of:0000000000000191" : { | ||
| 68 | + "segmentrouting" : { | ||
| 69 | + "name" : "Spine-R1", | ||
| 70 | + "nodeSid" : 103, | ||
| 71 | + "routerIp" : "192.168.0.11", | ||
| 72 | + "routerMac" : "00:00:01:00:11:80", | ||
| 73 | + "isEdgeRouter" : false, | ||
| 74 | + "adjacencySids" : [] | ||
| 75 | + } | ||
| 76 | + }, | ||
| 77 | + "of:0000000000000192" : { | ||
| 78 | + "segmentrouting" : { | ||
| 79 | + "name" : "Spine-R2", | ||
| 80 | + "nodeSid" : 104, | ||
| 81 | + "routerIp" : "192.168.0.22", | ||
| 82 | + "routerMac" : "00:00:01:00:22:80", | ||
| 83 | + "isEdgeRouter" : false, | ||
| 84 | + "adjacencySids" : [] | ||
| 85 | + } | ||
| 86 | + } | ||
| 87 | + }, | ||
| 88 | + "hosts" : { | ||
| 89 | + "00:00:00:00:00:01/4093" : { | ||
| 90 | + "basic": { | ||
| 91 | + "ips": ["10.0.1.1"], | ||
| 92 | + "location": "of:0000000000000001/3" | ||
| 93 | + } | ||
| 94 | + }, | ||
| 95 | + "00:00:00:00:00:02/4093" : { | ||
| 96 | + "basic": { | ||
| 97 | + "ips": ["10.0.1.2"], | ||
| 98 | + "location": "of:0000000000000001/4" | ||
| 99 | + } | ||
| 100 | + }, | ||
| 101 | + "00:00:00:00:00:03/4093" : { | ||
| 102 | + "basic": { | ||
| 103 | + "ips": ["10.0.2.1"], | ||
| 104 | + "location": "of:0000000000000002/3" | ||
| 105 | + } | ||
| 106 | + }, | ||
| 107 | + "00:00:00:00:00:04/4093" : { | ||
| 108 | + "basic": { | ||
| 109 | + "ips": ["10.0.2.2"], | ||
| 110 | + "location": "of:0000000000000002/4" | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | +} |
| ... | @@ -4,8 +4,7 @@ | ... | @@ -4,8 +4,7 @@ |
| 4 | "interfaces" : [ | 4 | "interfaces" : [ |
| 5 | { | 5 | { |
| 6 | "ips" : [ "10.0.1.254/24" ], | 6 | "ips" : [ "10.0.1.254/24" ], |
| 7 | - "mac" : "08:9e:01:82:38:68", | 7 | + "vlan" : "-1" |
| 8 | - "vlan" : "100" | ||
| 9 | } | 8 | } |
| 10 | ] | 9 | ] |
| 11 | }, | 10 | }, |
| ... | @@ -13,8 +12,7 @@ | ... | @@ -13,8 +12,7 @@ |
| 13 | "interfaces" : [ | 12 | "interfaces" : [ |
| 14 | { | 13 | { |
| 15 | "ips" : [ "10.0.1.254/24" ], | 14 | "ips" : [ "10.0.1.254/24" ], |
| 16 | - "mac" : "08:9e:01:82:38:68", | 15 | + "vlan" : "-1" |
| 17 | - "vlan" : "100" | ||
| 18 | } | 16 | } |
| 19 | ] | 17 | ] |
| 20 | }, | 18 | }, |
| ... | @@ -22,8 +20,7 @@ | ... | @@ -22,8 +20,7 @@ |
| 22 | "interfaces" : [ | 20 | "interfaces" : [ |
| 23 | { | 21 | { |
| 24 | "ips" : [ "10.0.2.254/24" ], | 22 | "ips" : [ "10.0.2.254/24" ], |
| 25 | - "mac" : "08:9e:01:82:38:68", | 23 | + "vlan" : "-1" |
| 26 | - "vlan" : "100" | ||
| 27 | } | 24 | } |
| 28 | ] | 25 | ] |
| 29 | }, | 26 | }, |
| ... | @@ -31,8 +28,7 @@ | ... | @@ -31,8 +28,7 @@ |
| 31 | "interfaces" : [ | 28 | "interfaces" : [ |
| 32 | { | 29 | { |
| 33 | "ips" : [ "10.0.2.254/24" ], | 30 | "ips" : [ "10.0.2.254/24" ], |
| 34 | - "mac" : "08:9e:01:82:38:68", | 31 | + "vlan" : "-1" |
| 35 | - "vlan" : "100" | ||
| 36 | } | 32 | } |
| 37 | ] | 33 | ] |
| 38 | } | 34 | } | ... | ... |
| ... | @@ -4,8 +4,7 @@ | ... | @@ -4,8 +4,7 @@ |
| 4 | "interfaces" : [ | 4 | "interfaces" : [ |
| 5 | { | 5 | { |
| 6 | "ips" : [ "10.0.1.254/24" ], | 6 | "ips" : [ "10.0.1.254/24" ], |
| 7 | - "mac" : "08:9e:01:82:38:68", | 7 | + "vlan" : "-1" |
| 8 | - "vlan" : "100" | ||
| 9 | } | 8 | } |
| 10 | ] | 9 | ] |
| 11 | }, | 10 | }, |
| ... | @@ -13,8 +12,7 @@ | ... | @@ -13,8 +12,7 @@ |
| 13 | "interfaces" : [ | 12 | "interfaces" : [ |
| 14 | { | 13 | { |
| 15 | "ips" : [ "10.0.1.254/24" ], | 14 | "ips" : [ "10.0.1.254/24" ], |
| 16 | - "mac" : "08:9e:01:82:38:68", | 15 | + "vlan" : "-1" |
| 17 | - "vlan" : "100" | ||
| 18 | } | 16 | } |
| 19 | ] | 17 | ] |
| 20 | }, | 18 | }, |
| ... | @@ -22,8 +20,7 @@ | ... | @@ -22,8 +20,7 @@ |
| 22 | "interfaces" : [ | 20 | "interfaces" : [ |
| 23 | { | 21 | { |
| 24 | "ips" : [ "10.0.2.254/24" ], | 22 | "ips" : [ "10.0.2.254/24" ], |
| 25 | - "mac" : "08:9e:01:82:38:68", | 23 | + "vlan" : "-1" |
| 26 | - "vlan" : "100" | ||
| 27 | } | 24 | } |
| 28 | ] | 25 | ] |
| 29 | }, | 26 | }, |
| ... | @@ -31,8 +28,7 @@ | ... | @@ -31,8 +28,7 @@ |
| 31 | "interfaces" : [ | 28 | "interfaces" : [ |
| 32 | { | 29 | { |
| 33 | "ips" : [ "10.0.2.254/24" ], | 30 | "ips" : [ "10.0.2.254/24" ], |
| 34 | - "mac" : "08:9e:01:82:38:68", | 31 | + "vlan" : "-1" |
| 35 | - "vlan" : "100" | ||
| 36 | } | 32 | } |
| 37 | ] | 33 | ] |
| 38 | }, | 34 | }, |
| ... | @@ -40,8 +36,7 @@ | ... | @@ -40,8 +36,7 @@ |
| 40 | "interfaces" : [ | 36 | "interfaces" : [ |
| 41 | { | 37 | { |
| 42 | "ips" : [ "10.0.3.254/24" ], | 38 | "ips" : [ "10.0.3.254/24" ], |
| 43 | - "mac" : "08:9e:01:82:38:68", | 39 | + "vlan" : "-1" |
| 44 | - "vlan" : "100" | ||
| 45 | } | 40 | } |
| 46 | ] | 41 | ] |
| 47 | }, | 42 | }, |
| ... | @@ -49,8 +44,7 @@ | ... | @@ -49,8 +44,7 @@ |
| 49 | "interfaces" : [ | 44 | "interfaces" : [ |
| 50 | { | 45 | { |
| 51 | "ips" : [ "10.0.3.254/24" ], | 46 | "ips" : [ "10.0.3.254/24" ], |
| 52 | - "mac" : "08:9e:01:82:38:68", | 47 | + "vlan" : "-1" |
| 53 | - "vlan" : "100" | ||
| 54 | } | 48 | } |
| 55 | ] | 49 | ] |
| 56 | }, | 50 | }, |
| ... | @@ -58,8 +52,7 @@ | ... | @@ -58,8 +52,7 @@ |
| 58 | "interfaces" : [ | 52 | "interfaces" : [ |
| 59 | { | 53 | { |
| 60 | "ips" : [ "10.0.4.254/24" ], | 54 | "ips" : [ "10.0.4.254/24" ], |
| 61 | - "mac" : "08:9e:01:82:38:68", | 55 | + "vlan" : "-1" |
| 62 | - "vlan" : "100" | ||
| 63 | } | 56 | } |
| 64 | ] | 57 | ] |
| 65 | }, | 58 | }, |
| ... | @@ -67,8 +60,7 @@ | ... | @@ -67,8 +60,7 @@ |
| 67 | "interfaces" : [ | 60 | "interfaces" : [ |
| 68 | { | 61 | { |
| 69 | "ips" : [ "10.0.4.254/24" ], | 62 | "ips" : [ "10.0.4.254/24" ], |
| 70 | - "mac" : "08:9e:01:82:38:68", | 63 | + "vlan" : "-1" |
| 71 | - "vlan" : "100" | ||
| 72 | } | 64 | } |
| 73 | ] | 65 | ] |
| 74 | } | 66 | } | ... | ... |
-
Please register or login to post a comment