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