Committed by
Gerrit Code Review
CORD-512 Support vSG <-> vRouter default route
- Support multiple subnets per port. getIpPort() will only return the first non-/32 and non-/0 subnet /32 is used as vSG subnet /0 is used as default gateway - Support multiple L3 unicast group on a single port Change the way to generate the group ID and group key - Special case for 0.0.0.0 host. Push a /0 to IP table instead of /32 - Implement vRouterConfig Put VR MAC to TMAC table of all leaves when config added When processEthDst see PortNumber.ANY in key, match ETH_DST only - For OFDPA, wipe existing instruction before sending to controller So packet that misses L3 unicast table won't be sent to controller twice - For SpringOpenTTP, pop VLAN before sending to controller - Move several constant definitions to SegmentRoutingService - Add minimum priority for IP rules such that /0 won't collide with zero priority default rules - Update the config sample Use VLAN=-1 for hosts Add example for default route Change-Id: Id751697ce36a7e5c13b3859350ff21b585c38525
Showing
21 changed files
with
827 additions
and
144 deletions
... | @@ -97,6 +97,14 @@ | ... | @@ -97,6 +97,14 @@ |
97 | <artifactId>onlab-junit</artifactId> | 97 | <artifactId>onlab-junit</artifactId> |
98 | <scope>test</scope> | 98 | <scope>test</scope> |
99 | </dependency> | 99 | </dependency> |
100 | + | ||
101 | + <dependency> | ||
102 | + <groupId>org.onosproject</groupId> | ||
103 | + <artifactId>onos-api</artifactId> | ||
104 | + <version>${project.version}</version> | ||
105 | + <scope>test</scope> | ||
106 | + <classifier>tests</classifier> | ||
107 | + </dependency> | ||
100 | </dependencies> | 108 | </dependencies> |
101 | 109 | ||
102 | <build> | 110 | <build> | ... | ... |
... | @@ -168,7 +168,7 @@ public class IcmpHandler { | ... | @@ -168,7 +168,7 @@ public class IcmpHandler { |
168 | treatment, ByteBuffer.wrap(payload.serialize())); | 168 | treatment, ByteBuffer.wrap(payload.serialize())); |
169 | srManager.packetService.emit(packet); | 169 | srManager.packetService.emit(packet); |
170 | } else { | 170 | } else { |
171 | - log.warn("Send a MPLS packet as a ICMP response"); | 171 | + log.info("Send a MPLS packet as a ICMP response"); |
172 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 172 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
173 | .setOutput(outport.port()) | 173 | .setOutput(outport.port()) |
174 | .build(); | 174 | .build(); | ... | ... |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/NetworkConfigEventHandler.java
0 → 100644
1 | +package org.onosproject.segmentrouting; | ||
2 | + | ||
3 | +import com.google.common.collect.ImmutableSet; | ||
4 | +import org.onlab.packet.MacAddress; | ||
5 | +import org.onosproject.net.DeviceId; | ||
6 | +import org.onosproject.net.PortNumber; | ||
7 | +import org.onosproject.net.config.NetworkConfigEvent; | ||
8 | +import org.onosproject.net.device.DeviceService; | ||
9 | +import org.onosproject.net.flow.criteria.Criteria; | ||
10 | +import org.onosproject.net.flowobjective.DefaultFilteringObjective; | ||
11 | +import org.onosproject.net.flowobjective.FilteringObjective; | ||
12 | +import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; | ||
13 | +import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig; | ||
14 | +import org.slf4j.Logger; | ||
15 | +import org.slf4j.LoggerFactory; | ||
16 | + | ||
17 | +import java.util.HashSet; | ||
18 | +import java.util.Set; | ||
19 | + | ||
20 | +/** | ||
21 | + * Handles network config events. | ||
22 | + */ | ||
23 | +public class NetworkConfigEventHandler { | ||
24 | + private static final Logger log = LoggerFactory.getLogger(NetworkConfigEventHandler.class); | ||
25 | + private final SegmentRoutingManager srManager; | ||
26 | + private final DeviceService deviceService; | ||
27 | + | ||
28 | + /** | ||
29 | + * Constructs Network Config Event Handler. | ||
30 | + * | ||
31 | + * @param srManager instance of {@link SegmentRoutingManager} | ||
32 | + */ | ||
33 | + public NetworkConfigEventHandler(SegmentRoutingManager srManager) { | ||
34 | + this.srManager = srManager; | ||
35 | + this.deviceService = srManager.deviceService; | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * Processes vRouter config added event. | ||
40 | + * | ||
41 | + * @param event network config added event | ||
42 | + */ | ||
43 | + protected void processVRouterConfigAdded(NetworkConfigEvent event) { | ||
44 | + log.info("Processing vRouter CONFIG_ADDED"); | ||
45 | + SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get(); | ||
46 | + deviceService.getAvailableDevices().forEach(device -> { | ||
47 | + populateVRouter(device.id(), getMacAddresses(config)); | ||
48 | + }); | ||
49 | + } | ||
50 | + | ||
51 | + /** | ||
52 | + * Processes vRouter config updated event. | ||
53 | + * | ||
54 | + * @param event network config updated event | ||
55 | + */ | ||
56 | + protected void processVRouterConfigUpdated(NetworkConfigEvent event) { | ||
57 | + log.info("Processing vRouter CONFIG_UPDATED"); | ||
58 | + SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get(); | ||
59 | + SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get(); | ||
60 | + deviceService.getAvailableDevices().forEach(device -> { | ||
61 | + Set<MacAddress> macAddresses = getMacAddresses(config); | ||
62 | + Set<MacAddress> prevMacAddresses = getMacAddresses(prevConfig); | ||
63 | + // Avoid removing and re-adding unchanged MAC addresses since | ||
64 | + // FlowObjective does not guarantee the execution order. | ||
65 | + Set<MacAddress> sameMacAddresses = new HashSet<>(macAddresses); | ||
66 | + sameMacAddresses.retainAll(prevMacAddresses); | ||
67 | + macAddresses.removeAll(sameMacAddresses); | ||
68 | + prevMacAddresses.removeAll(sameMacAddresses); | ||
69 | + | ||
70 | + revokeVRouter(device.id(), prevMacAddresses); | ||
71 | + populateVRouter(device.id(), macAddresses); | ||
72 | + }); | ||
73 | + | ||
74 | + } | ||
75 | + | ||
76 | + /** | ||
77 | + * Processes vRouter config removed event. | ||
78 | + * | ||
79 | + * @param event network config removed event | ||
80 | + */ | ||
81 | + protected void processVRouterConfigRemoved(NetworkConfigEvent event) { | ||
82 | + log.info("Processing vRouter CONFIG_REMOVED"); | ||
83 | + SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get(); | ||
84 | + deviceService.getAvailableDevices().forEach(device -> { | ||
85 | + revokeVRouter(device.id(), getMacAddresses(prevConfig)); | ||
86 | + }); | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * Populates initial vRouter rules. | ||
91 | + * | ||
92 | + * @param deviceId device ID | ||
93 | + */ | ||
94 | + public void initVRouters(DeviceId deviceId) { | ||
95 | + SegmentRoutingAppConfig config = | ||
96 | + srManager.cfgService.getConfig(srManager.appId, SegmentRoutingAppConfig.class); | ||
97 | + populateVRouter(deviceId, getMacAddresses(config)); | ||
98 | + } | ||
99 | + | ||
100 | + private void populateVRouter(DeviceId deviceId, Set<MacAddress> pendingAdd) { | ||
101 | + if (!isEdge(deviceId)) { | ||
102 | + return; | ||
103 | + } | ||
104 | + getVRouterFlowObjBuilders(pendingAdd).forEach(foBuilder -> { | ||
105 | + srManager.flowObjectiveService. | ||
106 | + filter(deviceId, foBuilder.add(new SRObjectiveContext(deviceId, | ||
107 | + SRObjectiveContext.ObjectiveType.FILTER))); | ||
108 | + }); | ||
109 | + } | ||
110 | + | ||
111 | + private void revokeVRouter(DeviceId deviceId, Set<MacAddress> pendingRemove) { | ||
112 | + if (!isEdge(deviceId)) { | ||
113 | + return; | ||
114 | + } | ||
115 | + getVRouterFlowObjBuilders(pendingRemove).forEach(foBuilder -> { | ||
116 | + srManager.flowObjectiveService. | ||
117 | + filter(deviceId, foBuilder.remove(new SRObjectiveContext(deviceId, | ||
118 | + SRObjectiveContext.ObjectiveType.FILTER))); | ||
119 | + }); | ||
120 | + } | ||
121 | + | ||
122 | + private Set<FilteringObjective.Builder> getVRouterFlowObjBuilders(Set<MacAddress> macAddresses) { | ||
123 | + ImmutableSet.Builder<FilteringObjective.Builder> setBuilder = ImmutableSet.builder(); | ||
124 | + macAddresses.forEach(macAddress -> { | ||
125 | + FilteringObjective.Builder fobuilder = DefaultFilteringObjective.builder(); | ||
126 | + fobuilder.withKey(Criteria.matchInPort(PortNumber.ANY)) | ||
127 | + .addCondition(Criteria.matchEthDst(macAddress)) | ||
128 | + .permit() | ||
129 | + .withPriority(SegmentRoutingService.DEFAULT_PRIORITY) | ||
130 | + .fromApp(srManager.appId); | ||
131 | + setBuilder.add(fobuilder); | ||
132 | + }); | ||
133 | + return setBuilder.build(); | ||
134 | + } | ||
135 | + | ||
136 | + private Set<MacAddress> getMacAddresses(SegmentRoutingAppConfig config) { | ||
137 | + if (config == null) { | ||
138 | + return ImmutableSet.of(); | ||
139 | + } | ||
140 | + | ||
141 | + HashSet<MacAddress> macAddresses = new HashSet<>(); | ||
142 | + config.vRouterMacs().forEach(mac -> { | ||
143 | + macAddresses.add(mac); | ||
144 | + }); | ||
145 | + return ImmutableSet.copyOf(macAddresses); | ||
146 | + } | ||
147 | + | ||
148 | + private boolean isEdge(DeviceId deviceId) { | ||
149 | + try { | ||
150 | + if (srManager.deviceConfiguration.isEdgeDevice(deviceId)) { | ||
151 | + return true; | ||
152 | + } | ||
153 | + } catch (DeviceConfigNotFoundException e) { } | ||
154 | + return false; | ||
155 | + } | ||
156 | +} |
... | @@ -39,11 +39,8 @@ import org.onosproject.net.flowobjective.DefaultFilteringObjective; | ... | @@ -39,11 +39,8 @@ import org.onosproject.net.flowobjective.DefaultFilteringObjective; |
39 | import org.onosproject.net.flowobjective.DefaultForwardingObjective; | 39 | import org.onosproject.net.flowobjective.DefaultForwardingObjective; |
40 | import org.onosproject.net.flowobjective.FilteringObjective; | 40 | import org.onosproject.net.flowobjective.FilteringObjective; |
41 | import org.onosproject.net.flowobjective.ForwardingObjective; | 41 | import org.onosproject.net.flowobjective.ForwardingObjective; |
42 | -import org.onosproject.net.flowobjective.Objective; | ||
43 | -import org.onosproject.net.flowobjective.ObjectiveError; | ||
44 | import org.onosproject.net.flowobjective.ForwardingObjective.Builder; | 42 | import org.onosproject.net.flowobjective.ForwardingObjective.Builder; |
45 | import org.onosproject.net.flowobjective.ForwardingObjective.Flag; | 43 | import org.onosproject.net.flowobjective.ForwardingObjective.Flag; |
46 | -import org.onosproject.net.flowobjective.ObjectiveContext; | ||
47 | import org.slf4j.Logger; | 44 | import org.slf4j.Logger; |
48 | import org.slf4j.LoggerFactory; | 45 | import org.slf4j.LoggerFactory; |
49 | 46 | ||
... | @@ -67,14 +64,6 @@ public class RoutingRulePopulator { | ... | @@ -67,14 +64,6 @@ public class RoutingRulePopulator { |
67 | private SegmentRoutingManager srManager; | 64 | private SegmentRoutingManager srManager; |
68 | private DeviceConfiguration config; | 65 | private DeviceConfiguration config; |
69 | 66 | ||
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; | ||
75 | - private static final long OFPP_MAX = 0xffffff00L; | ||
76 | - | ||
77 | - | ||
78 | /** | 67 | /** |
79 | * Creates a RoutingRulePopulator object. | 68 | * Creates a RoutingRulePopulator object. |
80 | * | 69 | * |
... | @@ -160,12 +149,21 @@ public class RoutingRulePopulator { | ... | @@ -160,12 +149,21 @@ public class RoutingRulePopulator { |
160 | throws DeviceConfigNotFoundException { | 149 | throws DeviceConfigNotFoundException { |
161 | MacAddress deviceMac; | 150 | MacAddress deviceMac; |
162 | deviceMac = config.getDeviceMac(deviceId); | 151 | deviceMac = config.getDeviceMac(deviceId); |
152 | + int priority; | ||
163 | 153 | ||
164 | TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); | 154 | TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); |
165 | TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); | 155 | TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); |
166 | 156 | ||
167 | sbuilder.matchEthType(Ethernet.TYPE_IPV4); | 157 | sbuilder.matchEthType(Ethernet.TYPE_IPV4); |
168 | - sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH)); | 158 | + // Special case for default route |
159 | + if (hostIp.isZero()) { | ||
160 | + sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 0)); | ||
161 | + priority = SegmentRoutingService.MIN_IP_PRIORITY; | ||
162 | + } else { | ||
163 | + Ip4Prefix hostIpPrefix = Ip4Prefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH); | ||
164 | + sbuilder.matchIPDst(hostIpPrefix); | ||
165 | + priority = getPriorityFromPrefix(hostIpPrefix); | ||
166 | + } | ||
169 | TrafficSelector selector = sbuilder.build(); | 167 | TrafficSelector selector = sbuilder.build(); |
170 | 168 | ||
171 | tbuilder.deferred() | 169 | tbuilder.deferred() |
... | @@ -192,7 +190,8 @@ public class RoutingRulePopulator { | ... | @@ -192,7 +190,8 @@ public class RoutingRulePopulator { |
192 | .withSelector(selector) | 190 | .withSelector(selector) |
193 | .nextStep(portNextObjId) | 191 | .nextStep(portNextObjId) |
194 | .fromApp(srManager.appId).makePermanent() | 192 | .fromApp(srManager.appId).makePermanent() |
195 | - .withPriority(DEFAULT_PRIORITY).withFlag(ForwardingObjective.Flag.SPECIFIC); | 193 | + .withPriority(priority) |
194 | + .withFlag(ForwardingObjective.Flag.SPECIFIC); | ||
196 | } | 195 | } |
197 | 196 | ||
198 | /** | 197 | /** |
... | @@ -277,7 +276,7 @@ public class RoutingRulePopulator { | ... | @@ -277,7 +276,7 @@ public class RoutingRulePopulator { |
277 | .makePermanent() | 276 | .makePermanent() |
278 | .nextStep(nextId) | 277 | .nextStep(nextId) |
279 | .withSelector(selector) | 278 | .withSelector(selector) |
280 | - .withPriority(2000 * ipPrefix.prefixLength()) | 279 | + .withPriority(getPriorityFromPrefix(ipPrefix)) |
281 | .withFlag(ForwardingObjective.Flag.SPECIFIC); | 280 | .withFlag(ForwardingObjective.Flag.SPECIFIC); |
282 | if (treatment != null) { | 281 | if (treatment != null) { |
283 | fwdBuilder.withTreatment(treatment); | 282 | fwdBuilder.withTreatment(treatment); |
... | @@ -386,7 +385,7 @@ public class RoutingRulePopulator { | ... | @@ -386,7 +385,7 @@ public class RoutingRulePopulator { |
386 | for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) { | 385 | for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) { |
387 | ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId) | 386 | ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId) |
388 | .makePermanent()).withSelector(selector) | 387 | .makePermanent()).withSelector(selector) |
389 | - .withPriority(DEFAULT_PRIORITY)) | 388 | + .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)) |
390 | .withFlag(ForwardingObjective.Flag.SPECIFIC); | 389 | .withFlag(ForwardingObjective.Flag.SPECIFIC); |
391 | srManager.flowObjectiveService. | 390 | srManager.flowObjectiveService. |
392 | forward(deviceId, | 391 | forward(deviceId, |
... | @@ -472,7 +471,9 @@ public class RoutingRulePopulator { | ... | @@ -472,7 +471,9 @@ public class RoutingRulePopulator { |
472 | } | 471 | } |
473 | 472 | ||
474 | for (Port port : srManager.deviceService.getPorts(deviceId)) { | 473 | for (Port port : srManager.deviceService.getPorts(deviceId)) { |
475 | - if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) { | 474 | + if (port.number().toLong() > 0 && |
475 | + port.number().toLong() < SegmentRoutingService.OFPP_MAX && | ||
476 | + port.isEnabled()) { | ||
476 | Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number()); | 477 | Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number()); |
477 | VlanId assignedVlan = (portSubnet == null) | 478 | VlanId assignedVlan = (portSubnet == null) |
478 | ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET) | 479 | ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET) |
... | @@ -482,7 +483,7 @@ public class RoutingRulePopulator { | ... | @@ -482,7 +483,7 @@ public class RoutingRulePopulator { |
482 | fob.withKey(Criteria.matchInPort(port.number())) | 483 | fob.withKey(Criteria.matchInPort(port.number())) |
483 | .addCondition(Criteria.matchEthDst(deviceMac)) | 484 | .addCondition(Criteria.matchEthDst(deviceMac)) |
484 | .addCondition(Criteria.matchVlanId(VlanId.NONE)) | 485 | .addCondition(Criteria.matchVlanId(VlanId.NONE)) |
485 | - .withPriority(DEFAULT_PRIORITY); | 486 | + .withPriority(SegmentRoutingService.DEFAULT_PRIORITY); |
486 | // vlan assignment is valid only if this instance is master | 487 | // vlan assignment is valid only if this instance is master |
487 | if (srManager.mastershipService.isLocalMaster(deviceId)) { | 488 | if (srManager.mastershipService.isLocalMaster(deviceId)) { |
488 | TrafficTreatment tt = DefaultTrafficTreatment.builder() | 489 | TrafficTreatment tt = DefaultTrafficTreatment.builder() |
... | @@ -520,7 +521,7 @@ public class RoutingRulePopulator { | ... | @@ -520,7 +521,7 @@ public class RoutingRulePopulator { |
520 | return; | 521 | return; |
521 | } | 522 | } |
522 | ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder(); | 523 | ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder(); |
523 | - Set<Ip4Address> allIps = new HashSet<Ip4Address>(config.getPortIPs(deviceId)); | 524 | + Set<Ip4Address> allIps = new HashSet<>(config.getPortIPs(deviceId)); |
524 | allIps.add(routerIp); | 525 | allIps.add(routerIp); |
525 | for (Ip4Address ipaddr : allIps) { | 526 | for (Ip4Address ipaddr : allIps) { |
526 | TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); | 527 | TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); |
... | @@ -532,7 +533,7 @@ public class RoutingRulePopulator { | ... | @@ -532,7 +533,7 @@ public class RoutingRulePopulator { |
532 | puntIp.withSelector(sbuilder.build()); | 533 | puntIp.withSelector(sbuilder.build()); |
533 | puntIp.withTreatment(tbuilder.build()); | 534 | puntIp.withTreatment(tbuilder.build()); |
534 | puntIp.withFlag(Flag.VERSATILE) | 535 | puntIp.withFlag(Flag.VERSATILE) |
535 | - .withPriority(HIGHEST_PRIORITY) | 536 | + .withPriority(SegmentRoutingService.HIGHEST_PRIORITY) |
536 | .makePermanent() | 537 | .makePermanent() |
537 | .fromApp(srManager.appId); | 538 | .fromApp(srManager.appId); |
538 | log.debug("Installing forwarding objective to punt port IP addresses"); | 539 | log.debug("Installing forwarding objective to punt port IP addresses"); |
... | @@ -576,7 +577,7 @@ public class RoutingRulePopulator { | ... | @@ -576,7 +577,7 @@ public class RoutingRulePopulator { |
576 | fob.withFlag(Flag.SPECIFIC) | 577 | fob.withFlag(Flag.SPECIFIC) |
577 | .withSelector(sbuilder.build()) | 578 | .withSelector(sbuilder.build()) |
578 | .nextStep(nextId) | 579 | .nextStep(nextId) |
579 | - .withPriority(FLOOD_PRIORITY) | 580 | + .withPriority(SegmentRoutingService.FLOOD_PRIORITY) |
580 | .fromApp(srManager.appId) | 581 | .fromApp(srManager.appId) |
581 | .makePermanent(); | 582 | .makePermanent(); |
582 | 583 | ||
... | @@ -611,7 +612,7 @@ public class RoutingRulePopulator { | ... | @@ -611,7 +612,7 @@ public class RoutingRulePopulator { |
611 | fob.withKey(Criteria.matchInPort(connectPoint.port())) | 612 | fob.withKey(Criteria.matchInPort(connectPoint.port())) |
612 | .addCondition(Criteria.matchVlanId(vlanId)) | 613 | .addCondition(Criteria.matchVlanId(vlanId)) |
613 | .addCondition(Criteria.matchEthDst(MacAddress.NONE)) | 614 | .addCondition(Criteria.matchEthDst(MacAddress.NONE)) |
614 | - .withPriority(XCONNECT_PRIORITY); | 615 | + .withPriority(SegmentRoutingService.XCONNECT_PRIORITY); |
615 | 616 | ||
616 | fob.permit().fromApp(srManager.appId); | 617 | fob.permit().fromApp(srManager.appId); |
617 | srManager.flowObjectiveService | 618 | srManager.flowObjectiveService |
... | @@ -657,7 +658,7 @@ public class RoutingRulePopulator { | ... | @@ -657,7 +658,7 @@ public class RoutingRulePopulator { |
657 | fob.withFlag(Flag.SPECIFIC) | 658 | fob.withFlag(Flag.SPECIFIC) |
658 | .withSelector(sbuilder.build()) | 659 | .withSelector(sbuilder.build()) |
659 | .nextStep(nextId) | 660 | .nextStep(nextId) |
660 | - .withPriority(DEFAULT_PRIORITY) | 661 | + .withPriority(SegmentRoutingService.DEFAULT_PRIORITY) |
661 | .fromApp(srManager.appId) | 662 | .fromApp(srManager.appId) |
662 | .makePermanent(); | 663 | .makePermanent(); |
663 | 664 | ||
... | @@ -671,29 +672,9 @@ public class RoutingRulePopulator { | ... | @@ -671,29 +672,9 @@ public class RoutingRulePopulator { |
671 | }); | 672 | }); |
672 | } | 673 | } |
673 | 674 | ||
674 | - private static class SRObjectiveContext implements ObjectiveContext { | 675 | + private int getPriorityFromPrefix(IpPrefix prefix) { |
675 | - enum ObjectiveType { | 676 | + return (prefix.isIp4()) ? |
676 | - FILTER, | 677 | + 2000 * prefix.prefixLength() + SegmentRoutingService.MIN_IP_PRIORITY : |
677 | - FORWARDING | 678 | + 500 * prefix.prefixLength() + SegmentRoutingService.MIN_IP_PRIORITY; |
678 | - } | ||
679 | - final DeviceId deviceId; | ||
680 | - final ObjectiveType type; | ||
681 | - | ||
682 | - SRObjectiveContext(DeviceId deviceId, ObjectiveType type) { | ||
683 | - this.deviceId = deviceId; | ||
684 | - this.type = type; | ||
685 | - } | ||
686 | - @Override | ||
687 | - public void onSuccess(Objective objective) { | ||
688 | - log.debug("{} objective operation successful in device {}", | ||
689 | - type.name(), deviceId); | ||
690 | - } | ||
691 | - | ||
692 | - @Override | ||
693 | - public void onError(Objective objective, ObjectiveError error) { | ||
694 | - log.warn("{} objective {} operation failed with error: {} in device {}", | ||
695 | - type.name(), objective, error, deviceId); | ||
696 | - } | ||
697 | } | 679 | } |
698 | - | ||
699 | } | 680 | } | ... | ... |
1 | +package org.onosproject.segmentrouting; | ||
2 | + | ||
3 | +import org.onosproject.net.DeviceId; | ||
4 | +import org.onosproject.net.flowobjective.Objective; | ||
5 | +import org.onosproject.net.flowobjective.ObjectiveContext; | ||
6 | +import org.onosproject.net.flowobjective.ObjectiveError; | ||
7 | +import org.slf4j.Logger; | ||
8 | +import org.slf4j.LoggerFactory; | ||
9 | + | ||
10 | +/** | ||
11 | + * Segment Routing Flow Objective Context. | ||
12 | + */ | ||
13 | +public class SRObjectiveContext implements ObjectiveContext { | ||
14 | + enum ObjectiveType { | ||
15 | + FILTER, | ||
16 | + FORWARDING | ||
17 | + } | ||
18 | + private final DeviceId deviceId; | ||
19 | + private final ObjectiveType type; | ||
20 | + | ||
21 | + private static final Logger log = LoggerFactory | ||
22 | + .getLogger(SegmentRoutingManager.class); | ||
23 | + | ||
24 | + SRObjectiveContext(DeviceId deviceId, ObjectiveType type) { | ||
25 | + this.deviceId = deviceId; | ||
26 | + this.type = type; | ||
27 | + } | ||
28 | + @Override | ||
29 | + public void onSuccess(Objective objective) { | ||
30 | + log.debug("{} objective operation successful in device {}", | ||
31 | + type.name(), deviceId); | ||
32 | + } | ||
33 | + | ||
34 | + @Override | ||
35 | + public void onError(Objective objective, ObjectiveError error) { | ||
36 | + log.warn("{} objective {} operation failed with error: {} in device {}", | ||
37 | + type.name(), objective, error, deviceId); | ||
38 | + } | ||
39 | +} | ||
40 | + |
... | @@ -54,7 +54,8 @@ import org.onosproject.net.host.HostListener; | ... | @@ -54,7 +54,8 @@ import org.onosproject.net.host.HostListener; |
54 | import org.onosproject.net.packet.PacketPriority; | 54 | import org.onosproject.net.packet.PacketPriority; |
55 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; | 55 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; |
56 | import org.onosproject.segmentrouting.config.DeviceConfiguration; | 56 | import org.onosproject.segmentrouting.config.DeviceConfiguration; |
57 | -import org.onosproject.segmentrouting.config.SegmentRoutingConfig; | 57 | +import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig; |
58 | +import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig; | ||
58 | import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; | 59 | import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; |
59 | import org.onosproject.segmentrouting.grouphandler.NeighborSet; | 60 | import org.onosproject.segmentrouting.grouphandler.NeighborSet; |
60 | import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey; | 61 | import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey; |
... | @@ -130,6 +131,12 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -130,6 +131,12 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
130 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 131 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
131 | protected MastershipService mastershipService; | 132 | protected MastershipService mastershipService; |
132 | 133 | ||
134 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
135 | + protected StorageService storageService; | ||
136 | + | ||
137 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
138 | + protected NetworkConfigRegistry cfgService; | ||
139 | + | ||
133 | protected ArpHandler arpHandler = null; | 140 | protected ArpHandler arpHandler = null; |
134 | protected IcmpHandler icmpHandler = null; | 141 | protected IcmpHandler icmpHandler = null; |
135 | protected IpHandler ipHandler = null; | 142 | protected IpHandler ipHandler = null; |
... | @@ -143,7 +150,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -143,7 +150,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
143 | private InternalPacketProcessor processor = null; | 150 | private InternalPacketProcessor processor = null; |
144 | private InternalLinkListener linkListener = null; | 151 | private InternalLinkListener linkListener = null; |
145 | private InternalDeviceListener deviceListener = null; | 152 | private InternalDeviceListener deviceListener = null; |
153 | + private NetworkConfigEventHandler netcfgHandler = null; | ||
146 | private InternalEventHandler eventHandler = new InternalEventHandler(); | 154 | private InternalEventHandler eventHandler = new InternalEventHandler(); |
155 | + private final InternalHostListener hostListener = new InternalHostListener(); | ||
147 | 156 | ||
148 | private ScheduledExecutorService executorService = Executors | 157 | private ScheduledExecutorService executorService = Executors |
149 | .newScheduledThreadPool(1); | 158 | .newScheduledThreadPool(1); |
... | @@ -181,27 +190,28 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -181,27 +190,28 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
181 | private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; | 190 | private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; |
182 | private EventuallyConsistentMap<String, Policy> policyStore = null; | 191 | private EventuallyConsistentMap<String, Policy> policyStore = null; |
183 | 192 | ||
184 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
185 | - protected StorageService storageService; | ||
186 | - | ||
187 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
188 | - protected NetworkConfigRegistry cfgService; | ||
189 | - | ||
190 | private final InternalConfigListener cfgListener = | 193 | private final InternalConfigListener cfgListener = |
191 | new InternalConfigListener(this); | 194 | new InternalConfigListener(this); |
192 | 195 | ||
193 | - @SuppressWarnings({ "unchecked", "rawtypes" }) | 196 | + private final ConfigFactory<DeviceId, SegmentRoutingDeviceConfig> cfgDeviceFactory = |
194 | - private final ConfigFactory cfgFactory = | 197 | + new ConfigFactory<DeviceId, SegmentRoutingDeviceConfig>(SubjectFactories.DEVICE_SUBJECT_FACTORY, |
195 | - new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY, | 198 | + SegmentRoutingDeviceConfig.class, |
196 | - SegmentRoutingConfig.class, | ||
197 | "segmentrouting") { | 199 | "segmentrouting") { |
198 | @Override | 200 | @Override |
199 | - public SegmentRoutingConfig createConfig() { | 201 | + public SegmentRoutingDeviceConfig createConfig() { |
200 | - return new SegmentRoutingConfig(); | 202 | + return new SegmentRoutingDeviceConfig(); |
201 | } | 203 | } |
202 | }; | 204 | }; |
203 | 205 | ||
204 | - private final InternalHostListener hostListener = new InternalHostListener(); | 206 | + private final ConfigFactory<ApplicationId, SegmentRoutingAppConfig> cfgAppFactory = |
207 | + new ConfigFactory<ApplicationId, SegmentRoutingAppConfig>(SubjectFactories.APP_SUBJECT_FACTORY, | ||
208 | + SegmentRoutingAppConfig.class, | ||
209 | + "segmentrouting") { | ||
210 | + @Override | ||
211 | + public SegmentRoutingAppConfig createConfig() { | ||
212 | + return new SegmentRoutingAppConfig(); | ||
213 | + } | ||
214 | + }; | ||
205 | 215 | ||
206 | private Object threadSchedulerLock = new Object(); | 216 | private Object threadSchedulerLock = new Object(); |
207 | private static int numOfEventsQueued = 0; | 217 | private static int numOfEventsQueued = 0; |
... | @@ -223,7 +233,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -223,7 +233,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
223 | @Activate | 233 | @Activate |
224 | protected void activate() { | 234 | protected void activate() { |
225 | appId = coreService | 235 | appId = coreService |
226 | - .registerApplication("org.onosproject.segmentrouting"); | 236 | + .registerApplication(SR_APP_ID); |
227 | 237 | ||
228 | kryoBuilder = new KryoNamespace.Builder() | 238 | kryoBuilder = new KryoNamespace.Builder() |
229 | .register(NeighborSetNextObjectiveStoreKey.class, | 239 | .register(NeighborSetNextObjectiveStoreKey.class, |
... | @@ -309,14 +319,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -309,14 +319,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
309 | .build(); | 319 | .build(); |
310 | 320 | ||
311 | cfgService.addListener(cfgListener); | 321 | cfgService.addListener(cfgListener); |
312 | - cfgService.registerConfigFactory(cfgFactory); | 322 | + cfgService.registerConfigFactory(cfgDeviceFactory); |
313 | - | 323 | + cfgService.registerConfigFactory(cfgAppFactory); |
314 | - hostService.addListener(hostListener); | ||
315 | 324 | ||
316 | processor = new InternalPacketProcessor(); | 325 | processor = new InternalPacketProcessor(); |
317 | linkListener = new InternalLinkListener(); | 326 | linkListener = new InternalLinkListener(); |
318 | deviceListener = new InternalDeviceListener(); | 327 | deviceListener = new InternalDeviceListener(); |
328 | + netcfgHandler = new NetworkConfigEventHandler(this); | ||
319 | 329 | ||
330 | + hostService.addListener(hostListener); | ||
320 | packetService.addProcessor(processor, PacketProcessor.director(2)); | 331 | packetService.addProcessor(processor, PacketProcessor.director(2)); |
321 | linkService.addListener(linkListener); | 332 | linkService.addListener(linkListener); |
322 | deviceService.addListener(deviceListener); | 333 | deviceService.addListener(deviceListener); |
... | @@ -334,7 +345,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -334,7 +345,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
334 | @Deactivate | 345 | @Deactivate |
335 | protected void deactivate() { | 346 | protected void deactivate() { |
336 | cfgService.removeListener(cfgListener); | 347 | cfgService.removeListener(cfgListener); |
337 | - cfgService.unregisterConfigFactory(cfgFactory); | 348 | + cfgService.unregisterConfigFactory(cfgDeviceFactory); |
349 | + cfgService.unregisterConfigFactory(cfgAppFactory); | ||
338 | 350 | ||
339 | // Withdraw ARP packet-in | 351 | // Withdraw ARP packet-in |
340 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 352 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
... | @@ -456,10 +468,17 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -456,10 +468,17 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
456 | nextAssignedVlan = (short) (Collections.min(assignedVlans) - 1); | 468 | nextAssignedVlan = (short) (Collections.min(assignedVlans) - 1); |
457 | } | 469 | } |
458 | for (Ip4Prefix unsub : unassignedSubnets) { | 470 | for (Ip4Prefix unsub : unassignedSubnets) { |
459 | - subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub), | 471 | + // Special case for default route. Assign default VLAN ID to /32 and /0 subnets |
460 | - VlanId.vlanId(nextAssignedVlan--)); | 472 | + if (unsub.prefixLength() == IpPrefix.MAX_INET_MASK_LENGTH || |
461 | - log.info("Assigned vlan: {} to subnet: {} on device: {}", | 473 | + unsub.prefixLength() == 0) { |
462 | - nextAssignedVlan + 1, unsub, deviceId); | 474 | + subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub), |
475 | + VlanId.vlanId(ASSIGNED_VLAN_NO_SUBNET)); | ||
476 | + } else { | ||
477 | + subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub), | ||
478 | + VlanId.vlanId(nextAssignedVlan--)); | ||
479 | + log.info("Assigned vlan: {} to subnet: {} on device: {}", | ||
480 | + nextAssignedVlan + 1, unsub, deviceId); | ||
481 | + } | ||
463 | } | 482 | } |
464 | 483 | ||
465 | return subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, subnet)); | 484 | return subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, subnet)); |
... | @@ -766,6 +785,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -766,6 +785,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
766 | groupHandler.createGroupsForXConnect(device.id()); | 785 | groupHandler.createGroupsForXConnect(device.id()); |
767 | routingRulePopulator.populateXConnectBroadcastRule(device.id()); | 786 | routingRulePopulator.populateXConnectBroadcastRule(device.id()); |
768 | } | 787 | } |
788 | + | ||
789 | + netcfgHandler.initVRouters(device.id()); | ||
769 | } | 790 | } |
770 | 791 | ||
771 | private void processPortRemoved(Device device, Port port) { | 792 | private void processPortRemoved(Device device, Port port) { |
... | @@ -851,14 +872,33 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -851,14 +872,33 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
851 | 872 | ||
852 | @Override | 873 | @Override |
853 | public void event(NetworkConfigEvent event) { | 874 | public void event(NetworkConfigEvent event) { |
854 | - if (event.configClass().equals(SegmentRoutingConfig.class)) { | 875 | + // TODO move this part to NetworkConfigEventHandler |
855 | - if (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED) { | 876 | + if (event.configClass().equals(SegmentRoutingDeviceConfig.class)) { |
856 | - log.info("Network configuration added."); | 877 | + switch (event.type()) { |
857 | - configureNetwork(); | 878 | + case CONFIG_ADDED: |
879 | + log.info("Segment Routing Config added."); | ||
880 | + configureNetwork(); | ||
881 | + break; | ||
882 | + case CONFIG_UPDATED: | ||
883 | + log.info("Segment Routing Config updated."); | ||
884 | + // TODO support dynamic configuration | ||
885 | + break; | ||
886 | + default: | ||
887 | + break; | ||
858 | } | 888 | } |
859 | - if (event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) { | 889 | + } else if (event.configClass().equals(SegmentRoutingAppConfig.class)) { |
860 | - log.info("Network configuration updated."); | 890 | + switch (event.type()) { |
861 | - // TODO support dynamic configuration | 891 | + case CONFIG_ADDED: |
892 | + netcfgHandler.processVRouterConfigAdded(event); | ||
893 | + break; | ||
894 | + case CONFIG_UPDATED: | ||
895 | + netcfgHandler.processVRouterConfigUpdated(event); | ||
896 | + break; | ||
897 | + case CONFIG_REMOVED: | ||
898 | + netcfgHandler.processVRouterConfigRemoved(event); | ||
899 | + break; | ||
900 | + default: | ||
901 | + break; | ||
862 | } | 902 | } |
863 | } | 903 | } |
864 | } | 904 | } | ... | ... |
... | @@ -21,6 +21,40 @@ import java.util.List; | ... | @@ -21,6 +21,40 @@ import java.util.List; |
21 | * Segment Routing Service for REST API. | 21 | * Segment Routing Service for REST API. |
22 | */ | 22 | */ |
23 | public interface SegmentRoutingService { | 23 | public interface SegmentRoutingService { |
24 | + /** | ||
25 | + * Segment Routing App ID. | ||
26 | + */ | ||
27 | + String SR_APP_ID = "org.onosproject.segmentrouting"; | ||
28 | + | ||
29 | + /** | ||
30 | + * Highest flow priority. | ||
31 | + */ | ||
32 | + int HIGHEST_PRIORITY = 0xffff; | ||
33 | + | ||
34 | + /** | ||
35 | + * VLAN cross-connect priority. | ||
36 | + */ | ||
37 | + int XCONNECT_PRIORITY = 1000; | ||
38 | + | ||
39 | + /** | ||
40 | + * Default flow priority. | ||
41 | + */ | ||
42 | + int DEFAULT_PRIORITY = 100; | ||
43 | + | ||
44 | + /** | ||
45 | + * Minimum IP priority. | ||
46 | + * | ||
47 | + * Should > 0 such that priority of /0 will not conflict with lowest | ||
48 | + * priority default entries. | ||
49 | + */ | ||
50 | + int MIN_IP_PRIORITY = 10; | ||
51 | + | ||
52 | + /** | ||
53 | + * Subnet flooding flow priority. | ||
54 | + */ | ||
55 | + int FLOOD_PRIORITY = 5; | ||
56 | + | ||
57 | + long OFPP_MAX = 0xffffff00L; | ||
24 | 58 | ||
25 | /** | 59 | /** |
26 | * Returns all tunnels. | 60 | * Returns all tunnels. | ... | ... |
... | @@ -15,9 +15,12 @@ | ... | @@ -15,9 +15,12 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.segmentrouting.config; | 16 | package org.onosproject.segmentrouting.config; |
17 | 17 | ||
18 | +import com.google.common.collect.HashMultimap; | ||
18 | import com.google.common.collect.ImmutableSet; | 19 | import com.google.common.collect.ImmutableSet; |
20 | +import com.google.common.collect.SetMultimap; | ||
19 | import org.onlab.packet.Ip4Address; | 21 | import org.onlab.packet.Ip4Address; |
20 | import org.onlab.packet.Ip4Prefix; | 22 | import org.onlab.packet.Ip4Prefix; |
23 | +import org.onlab.packet.IpPrefix; | ||
21 | import org.onlab.packet.MacAddress; | 24 | import org.onlab.packet.MacAddress; |
22 | import org.onlab.packet.VlanId; | 25 | import org.onlab.packet.VlanId; |
23 | import org.onosproject.incubator.net.config.basics.ConfigException; | 26 | import org.onosproject.incubator.net.config.basics.ConfigException; |
... | @@ -37,6 +40,7 @@ import java.util.HashSet; | ... | @@ -37,6 +40,7 @@ import java.util.HashSet; |
37 | import java.util.LinkedList; | 40 | import java.util.LinkedList; |
38 | import java.util.List; | 41 | import java.util.List; |
39 | import java.util.Map; | 42 | import java.util.Map; |
43 | +import java.util.Optional; | ||
40 | import java.util.Set; | 44 | import java.util.Set; |
41 | import java.util.concurrent.ConcurrentHashMap; | 45 | import java.util.concurrent.ConcurrentHashMap; |
42 | 46 | ||
... | @@ -59,13 +63,13 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -59,13 +63,13 @@ public class DeviceConfiguration implements DeviceProperties { |
59 | Ip4Address ip; | 63 | Ip4Address ip; |
60 | MacAddress mac; | 64 | MacAddress mac; |
61 | boolean isEdge; | 65 | boolean isEdge; |
62 | - HashMap<PortNumber, Ip4Address> gatewayIps; | 66 | + Map<PortNumber, Ip4Address> gatewayIps; |
63 | - HashMap<PortNumber, Ip4Prefix> subnets; | 67 | + SetMultimap<PortNumber, Ip4Prefix> subnets; |
64 | Map<Integer, Set<Integer>> adjacencySids; | 68 | Map<Integer, Set<Integer>> adjacencySids; |
65 | 69 | ||
66 | public SegmentRouterInfo() { | 70 | public SegmentRouterInfo() { |
67 | gatewayIps = new HashMap<>(); | 71 | gatewayIps = new HashMap<>(); |
68 | - subnets = new HashMap<>(); | 72 | + subnets = HashMultimap.create(); |
69 | } | 73 | } |
70 | } | 74 | } |
71 | 75 | ||
... | @@ -78,10 +82,10 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -78,10 +82,10 @@ public class DeviceConfiguration implements DeviceProperties { |
78 | public DeviceConfiguration(NetworkConfigRegistry cfgService) { | 82 | public DeviceConfiguration(NetworkConfigRegistry cfgService) { |
79 | // Read config from device subject, excluding gatewayIps and subnets. | 83 | // Read config from device subject, excluding gatewayIps and subnets. |
80 | Set<DeviceId> deviceSubjects = | 84 | Set<DeviceId> deviceSubjects = |
81 | - cfgService.getSubjects(DeviceId.class, SegmentRoutingConfig.class); | 85 | + cfgService.getSubjects(DeviceId.class, SegmentRoutingDeviceConfig.class); |
82 | deviceSubjects.forEach(subject -> { | 86 | deviceSubjects.forEach(subject -> { |
83 | - SegmentRoutingConfig config = | 87 | + SegmentRoutingDeviceConfig config = |
84 | - cfgService.getConfig(subject, SegmentRoutingConfig.class); | 88 | + cfgService.getConfig(subject, SegmentRoutingDeviceConfig.class); |
85 | SegmentRouterInfo info = new SegmentRouterInfo(); | 89 | SegmentRouterInfo info = new SegmentRouterInfo(); |
86 | info.deviceId = subject; | 90 | info.deviceId = subject; |
87 | info.nodeSid = config.nodeSid(); | 91 | info.nodeSid = config.nodeSid(); |
... | @@ -119,7 +123,11 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -119,7 +123,11 @@ public class DeviceConfiguration implements DeviceProperties { |
119 | // Extract subnet information | 123 | // Extract subnet information |
120 | Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses(); | 124 | Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses(); |
121 | interfaceAddresses.forEach(interfaceAddress -> { | 125 | interfaceAddresses.forEach(interfaceAddress -> { |
122 | - info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); | 126 | + // Do not add /0 and /32 to gateway IP list |
127 | + int prefixLength = interfaceAddress.subnetAddress().prefixLength(); | ||
128 | + if (prefixLength != 0 && prefixLength != IpPrefix.MAX_INET_MASK_LENGTH) { | ||
129 | + info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); | ||
130 | + } | ||
123 | info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); | 131 | info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); |
124 | }); | 132 | }); |
125 | 133 | ||
... | @@ -247,9 +255,13 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -247,9 +255,13 @@ public class DeviceConfiguration implements DeviceProperties { |
247 | Map<Ip4Prefix, List<PortNumber>> subnetPortMap = new HashMap<>(); | 255 | Map<Ip4Prefix, List<PortNumber>> subnetPortMap = new HashMap<>(); |
248 | 256 | ||
249 | // Construct subnet-port mapping from port-subnet mapping | 257 | // Construct subnet-port mapping from port-subnet mapping |
250 | - Map<PortNumber, Ip4Prefix> portSubnetMap = | 258 | + SetMultimap<PortNumber, Ip4Prefix> portSubnetMap = |
251 | this.deviceConfigMap.get(deviceId).subnets; | 259 | this.deviceConfigMap.get(deviceId).subnets; |
252 | - portSubnetMap.forEach((port, subnet) -> { | 260 | + |
261 | + portSubnetMap.entries().forEach(entry -> { | ||
262 | + PortNumber port = entry.getKey(); | ||
263 | + Ip4Prefix subnet = entry.getValue(); | ||
264 | + | ||
253 | if (subnetPortMap.containsKey(subnet)) { | 265 | if (subnetPortMap.containsKey(subnet)) { |
254 | subnetPortMap.get(subnet).add(port); | 266 | subnetPortMap.get(subnet).add(port); |
255 | } else { | 267 | } else { |
... | @@ -258,7 +270,6 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -258,7 +270,6 @@ public class DeviceConfiguration implements DeviceProperties { |
258 | subnetPortMap.put(subnet, ports); | 270 | subnetPortMap.put(subnet, ports); |
259 | } | 271 | } |
260 | }); | 272 | }); |
261 | - | ||
262 | return subnetPortMap; | 273 | return subnetPortMap; |
263 | } | 274 | } |
264 | 275 | ||
... | @@ -322,21 +333,6 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -322,21 +333,6 @@ public class DeviceConfiguration implements DeviceProperties { |
322 | } | 333 | } |
323 | 334 | ||
324 | /** | 335 | /** |
325 | - * Returns the configured IP addresses per port | ||
326 | - * for a segment router. | ||
327 | - * | ||
328 | - * @param deviceId device identifier | ||
329 | - * @return map of port to gateway IP addresses or null if not found | ||
330 | - */ | ||
331 | - public Map<PortNumber, Ip4Address> getPortIPMap(DeviceId deviceId) { | ||
332 | - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); | ||
333 | - if (srinfo != null) { | ||
334 | - return srinfo.gatewayIps; | ||
335 | - } | ||
336 | - return null; | ||
337 | - } | ||
338 | - | ||
339 | - /** | ||
340 | * Returns the configured subnet prefixes for a segment router. | 336 | * Returns the configured subnet prefixes for a segment router. |
341 | * | 337 | * |
342 | * @param deviceId device identifier | 338 | * @param deviceId device identifier |
... | @@ -353,8 +349,8 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -353,8 +349,8 @@ public class DeviceConfiguration implements DeviceProperties { |
353 | } | 349 | } |
354 | 350 | ||
355 | /** | 351 | /** |
356 | - * Returns the configured subnet on the given port, or null if no | 352 | + * Returns the configured non-/32 and non-/0 subnet on the given port, |
357 | - * subnet has been configured on the port. | 353 | + * or null if no subnet has been configured on the port. |
358 | * | 354 | * |
359 | * @param deviceId device identifier | 355 | * @param deviceId device identifier |
360 | * @param pnum port identifier | 356 | * @param pnum port identifier |
... | @@ -363,7 +359,12 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -363,7 +359,12 @@ public class DeviceConfiguration implements DeviceProperties { |
363 | public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) { | 359 | public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) { |
364 | SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); | 360 | SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); |
365 | if (srinfo != null) { | 361 | if (srinfo != null) { |
366 | - return srinfo.subnets.get(pnum); | 362 | + Optional<Ip4Prefix> result = srinfo.subnets.get(pnum).stream() |
363 | + .filter(subnet -> | ||
364 | + subnet.getIp4Prefix().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH && | ||
365 | + subnet.getIp4Prefix().prefixLength() != 0) | ||
366 | + .findFirst(); | ||
367 | + return (result.isPresent()) ? result.get() : null; | ||
367 | } | 368 | } |
368 | return null; | 369 | return null; |
369 | } | 370 | } |
... | @@ -378,7 +379,7 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -378,7 +379,7 @@ public class DeviceConfiguration implements DeviceProperties { |
378 | public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) { | 379 | public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) { |
379 | for (Map.Entry<DeviceId, SegmentRouterInfo> entry: | 380 | for (Map.Entry<DeviceId, SegmentRouterInfo> entry: |
380 | deviceConfigMap.entrySet()) { | 381 | deviceConfigMap.entrySet()) { |
381 | - for (Ip4Prefix prefix:entry.getValue().subnets.values()) { | 382 | + for (Ip4Prefix prefix : entry.getValue().subnets.values()) { |
382 | if (prefix.contains(destIpAddress)) { | 383 | if (prefix.contains(destIpAddress)) { |
383 | return entry.getValue().ip; | 384 | return entry.getValue().ip; |
384 | } | 385 | } |
... | @@ -428,7 +429,8 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -428,7 +429,8 @@ public class DeviceConfiguration implements DeviceProperties { |
428 | } | 429 | } |
429 | 430 | ||
430 | for (Ip4Prefix subnet: subnets) { | 431 | for (Ip4Prefix subnet: subnets) { |
431 | - if (subnet.contains(hostIp)) { | 432 | + // Exclude /0 since it is a special case used for default route |
433 | + if (subnet.prefixLength() != 0 && subnet.contains(hostIp)) { | ||
432 | return true; | 434 | return true; |
433 | } | 435 | } |
434 | } | 436 | } | ... | ... |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016 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.config; | ||
18 | + | ||
19 | +import com.fasterxml.jackson.databind.JsonNode; | ||
20 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
21 | +import com.google.common.collect.ImmutableSet; | ||
22 | +import org.onlab.packet.MacAddress; | ||
23 | +import org.onosproject.core.ApplicationId; | ||
24 | +import org.onosproject.net.config.Config; | ||
25 | +import java.util.Set; | ||
26 | + | ||
27 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
28 | + | ||
29 | +/** | ||
30 | + * App configuration object for Segment Routing. | ||
31 | + */ | ||
32 | +public class SegmentRoutingAppConfig extends Config<ApplicationId> { | ||
33 | + private static final String VROUTER_MACS = "vRouterMacs"; | ||
34 | + | ||
35 | + @Override | ||
36 | + public boolean isValid() { | ||
37 | + return hasOnlyFields(VROUTER_MACS) && vRouterMacs() != null; | ||
38 | + } | ||
39 | + | ||
40 | + /** | ||
41 | + * Gets vRouters from the config. | ||
42 | + * | ||
43 | + * @return a set of vRouter MAC addresses | ||
44 | + */ | ||
45 | + public Set<MacAddress> vRouterMacs() { | ||
46 | + if (!object.has(VROUTER_MACS)) { | ||
47 | + return null; | ||
48 | + } | ||
49 | + | ||
50 | + ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder(); | ||
51 | + ArrayNode arrayNode = (ArrayNode) object.path(VROUTER_MACS); | ||
52 | + for (JsonNode jsonNode : arrayNode) { | ||
53 | + MacAddress mac; | ||
54 | + | ||
55 | + String macStr = jsonNode.asText(null); | ||
56 | + if (macStr == null) { | ||
57 | + return null; | ||
58 | + } | ||
59 | + try { | ||
60 | + mac = MacAddress.valueOf(macStr); | ||
61 | + } catch (IllegalArgumentException e) { | ||
62 | + return null; | ||
63 | + } | ||
64 | + | ||
65 | + builder.add(mac); | ||
66 | + } | ||
67 | + return builder.build(); | ||
68 | + } | ||
69 | + | ||
70 | + /** | ||
71 | + * Sets vRouters to the config. | ||
72 | + * | ||
73 | + * @param vRouterMacs a set of vRouter MAC addresses | ||
74 | + * @return this {@link SegmentRoutingAppConfig} | ||
75 | + */ | ||
76 | + public SegmentRoutingAppConfig setVRouterMacs(Set<MacAddress> vRouterMacs) { | ||
77 | + if (vRouterMacs == null) { | ||
78 | + object.remove(VROUTER_MACS); | ||
79 | + } else { | ||
80 | + ArrayNode arrayNode = mapper.createArrayNode(); | ||
81 | + | ||
82 | + vRouterMacs.forEach(mac -> { | ||
83 | + arrayNode.add(mac.toString()); | ||
84 | + }); | ||
85 | + | ||
86 | + object.set(VROUTER_MACS, arrayNode); | ||
87 | + } | ||
88 | + return this; | ||
89 | + } | ||
90 | + | ||
91 | + @Override | ||
92 | + public String toString() { | ||
93 | + return toStringHelper(this) | ||
94 | + .add("vRouterMacs", vRouterMacs()) | ||
95 | + .toString(); | ||
96 | + } | ||
97 | +} |
... | @@ -34,7 +34,7 @@ import java.util.Set; | ... | @@ -34,7 +34,7 @@ import java.util.Set; |
34 | /** | 34 | /** |
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 SegmentRoutingDeviceConfig extends Config<DeviceId> { |
38 | private static final String NAME = "name"; | 38 | private static final String NAME = "name"; |
39 | private static final String IP = "routerIp"; | 39 | private static final String IP = "routerIp"; |
40 | private static final String MAC = "routerMac"; | 40 | private static final String MAC = "routerMac"; |
... | @@ -71,8 +71,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { | ... | @@ -71,8 +71,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { |
71 | * @param name name of the router. | 71 | * @param name name of the router. |
72 | * @return the config of the router. | 72 | * @return the config of the router. |
73 | */ | 73 | */ |
74 | - public SegmentRoutingConfig setName(String name) { | 74 | + public SegmentRoutingDeviceConfig setName(String name) { |
75 | - return (SegmentRoutingConfig) setOrClear(NAME, name); | 75 | + return (SegmentRoutingDeviceConfig) setOrClear(NAME, name); |
76 | } | 76 | } |
77 | 77 | ||
78 | /** | 78 | /** |
... | @@ -91,8 +91,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { | ... | @@ -91,8 +91,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { |
91 | * @param ip IP address of the router. | 91 | * @param ip IP address of the router. |
92 | * @return the config of the router. | 92 | * @return the config of the router. |
93 | */ | 93 | */ |
94 | - public SegmentRoutingConfig setRouterIp(String ip) { | 94 | + public SegmentRoutingDeviceConfig setRouterIp(String ip) { |
95 | - return (SegmentRoutingConfig) setOrClear(IP, ip); | 95 | + return (SegmentRoutingDeviceConfig) setOrClear(IP, ip); |
96 | } | 96 | } |
97 | 97 | ||
98 | /** | 98 | /** |
... | @@ -111,8 +111,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { | ... | @@ -111,8 +111,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { |
111 | * @param mac MAC address of the router. | 111 | * @param mac MAC address of the router. |
112 | * @return the config of the router. | 112 | * @return the config of the router. |
113 | */ | 113 | */ |
114 | - public SegmentRoutingConfig setRouterMac(String mac) { | 114 | + public SegmentRoutingDeviceConfig setRouterMac(String mac) { |
115 | - return (SegmentRoutingConfig) setOrClear(MAC, mac); | 115 | + return (SegmentRoutingDeviceConfig) setOrClear(MAC, mac); |
116 | } | 116 | } |
117 | 117 | ||
118 | /** | 118 | /** |
... | @@ -130,8 +130,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { | ... | @@ -130,8 +130,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { |
130 | * @param sid node SID of the router. | 130 | * @param sid node SID of the router. |
131 | * @return the config of the router. | 131 | * @return the config of the router. |
132 | */ | 132 | */ |
133 | - public SegmentRoutingConfig setNodeSid(int sid) { | 133 | + public SegmentRoutingDeviceConfig setNodeSid(int sid) { |
134 | - return (SegmentRoutingConfig) setOrClear(SID, sid); | 134 | + return (SegmentRoutingDeviceConfig) setOrClear(SID, sid); |
135 | } | 135 | } |
136 | 136 | ||
137 | /** | 137 | /** |
... | @@ -154,8 +154,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { | ... | @@ -154,8 +154,8 @@ public class SegmentRoutingConfig extends Config<DeviceId> { |
154 | * @param isEdgeRouter true if the router is an edge router. | 154 | * @param isEdgeRouter true if the router is an edge router. |
155 | * @return the config of the router. | 155 | * @return the config of the router. |
156 | */ | 156 | */ |
157 | - public SegmentRoutingConfig setIsEdgeRouter(boolean isEdgeRouter) { | 157 | + public SegmentRoutingDeviceConfig setIsEdgeRouter(boolean isEdgeRouter) { |
158 | - return (SegmentRoutingConfig) setOrClear(EDGE, isEdgeRouter); | 158 | + return (SegmentRoutingDeviceConfig) setOrClear(EDGE, isEdgeRouter); |
159 | } | 159 | } |
160 | 160 | ||
161 | /** | 161 | /** |
... | @@ -197,7 +197,7 @@ public class SegmentRoutingConfig extends Config<DeviceId> { | ... | @@ -197,7 +197,7 @@ public class SegmentRoutingConfig extends Config<DeviceId> { |
197 | * @param adjacencySids adjacency SIDs of the router. | 197 | * @param adjacencySids adjacency SIDs of the router. |
198 | * @return the config of the router. | 198 | * @return the config of the router. |
199 | */ | 199 | */ |
200 | - public SegmentRoutingConfig setAdjacencySids(Map<Integer, Set<Integer>> adjacencySids) { | 200 | + public SegmentRoutingDeviceConfig setAdjacencySids(Map<Integer, Set<Integer>> adjacencySids) { |
201 | if (adjacencySids == null) { | 201 | if (adjacencySids == null) { |
202 | object.remove(ADJSIDS); | 202 | object.remove(ADJSIDS); |
203 | } else { | 203 | } else { | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016 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.config; | ||
18 | + | ||
19 | +import com.fasterxml.jackson.databind.JsonNode; | ||
20 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
21 | +import com.google.common.collect.ImmutableSet; | ||
22 | +import org.junit.Before; | ||
23 | +import org.junit.Test; | ||
24 | +import org.onlab.packet.MacAddress; | ||
25 | +import org.onosproject.core.ApplicationId; | ||
26 | +import org.onosproject.TestApplicationId; | ||
27 | +import org.onosproject.net.config.Config; | ||
28 | +import org.onosproject.net.config.ConfigApplyDelegate; | ||
29 | +import org.onosproject.segmentrouting.SegmentRoutingService; | ||
30 | +import java.util.Set; | ||
31 | + | ||
32 | +import static org.hamcrest.Matchers.is; | ||
33 | +import static org.junit.Assert.assertThat; | ||
34 | +import static org.junit.Assert.assertTrue; | ||
35 | + | ||
36 | +/** | ||
37 | + * Tests for class {@link SegmentRoutingAppConfig}. | ||
38 | + */ | ||
39 | +public class SegmentRoutingAppConfigTest { | ||
40 | + private static final ApplicationId APP_ID = | ||
41 | + new TestApplicationId(SegmentRoutingService.SR_APP_ID); | ||
42 | + | ||
43 | + private SegmentRoutingAppConfig config; | ||
44 | + private MacAddress routerMac1; | ||
45 | + private MacAddress routerMac2; | ||
46 | + private MacAddress routerMac3; | ||
47 | + | ||
48 | + /** | ||
49 | + * Initialize test related variables. | ||
50 | + * | ||
51 | + * @throws Exception | ||
52 | + */ | ||
53 | + @Before | ||
54 | + public void setUp() throws Exception { | ||
55 | + String jsonString = "{" + | ||
56 | + "\"vRouterMacs\" : [" + | ||
57 | + " \"00:00:00:00:00:01\"," + | ||
58 | + " \"00:00:00:00:00:02\"" + | ||
59 | + "]}"; | ||
60 | + | ||
61 | + routerMac1 = MacAddress.valueOf("00:00:00:00:00:01"); | ||
62 | + routerMac2 = MacAddress.valueOf("00:00:00:00:00:02"); | ||
63 | + routerMac3 = MacAddress.valueOf("00:00:00:00:00:03"); | ||
64 | + | ||
65 | + ApplicationId subject = APP_ID; | ||
66 | + String key = SegmentRoutingService.SR_APP_ID; | ||
67 | + ObjectMapper mapper = new ObjectMapper(); | ||
68 | + JsonNode jsonNode = mapper.readTree(jsonString); | ||
69 | + ConfigApplyDelegate delegate = new MockDelegate(); | ||
70 | + | ||
71 | + config = new SegmentRoutingAppConfig(); | ||
72 | + config.init(subject, key, jsonNode, mapper, delegate); | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * Tests vRouters getter. | ||
77 | + * | ||
78 | + * @throws Exception | ||
79 | + */ | ||
80 | + @Test | ||
81 | + public void testVRouters() throws Exception { | ||
82 | + assertTrue(config.isValid()); | ||
83 | + | ||
84 | + Set<MacAddress> vRouters = config.vRouterMacs(); | ||
85 | + assertThat(vRouters.size(), is(2)); | ||
86 | + assertTrue(vRouters.contains(routerMac1)); | ||
87 | + assertTrue(vRouters.contains(routerMac2)); | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * Tests vRouters setter. | ||
92 | + * | ||
93 | + * @throws Exception | ||
94 | + */ | ||
95 | + @Test | ||
96 | + public void testSetVRouters() throws Exception { | ||
97 | + ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder(); | ||
98 | + builder.add(routerMac3); | ||
99 | + config.setVRouterMacs(builder.build()); | ||
100 | + | ||
101 | + Set<MacAddress> macs = config.vRouterMacs(); | ||
102 | + assertThat(macs.size(), is(1)); | ||
103 | + assertTrue(macs.contains(routerMac3)); | ||
104 | + } | ||
105 | + | ||
106 | + private class MockDelegate implements ConfigApplyDelegate { | ||
107 | + @Override | ||
108 | + public void onApply(Config config) { | ||
109 | + } | ||
110 | + } | ||
111 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -36,10 +36,10 @@ import static org.hamcrest.Matchers.is; | ... | @@ -36,10 +36,10 @@ import static org.hamcrest.Matchers.is; |
36 | import static org.junit.Assert.assertTrue; | 36 | import static org.junit.Assert.assertTrue; |
37 | 37 | ||
38 | /** | 38 | /** |
39 | - * Tests for class {@link SegmentRoutingConfig}. | 39 | + * Tests for class {@link SegmentRoutingDeviceConfig}. |
40 | */ | 40 | */ |
41 | -public class SegmentRoutingConfigTest { | 41 | +public class SegmentRoutingDeviceConfigTest { |
42 | - private SegmentRoutingConfig config; | 42 | + private SegmentRoutingDeviceConfig config; |
43 | private Map<Integer, Set<Integer>> adjacencySids1; | 43 | private Map<Integer, Set<Integer>> adjacencySids1; |
44 | private Map<Integer, Set<Integer>> adjacencySids2; | 44 | private Map<Integer, Set<Integer>> adjacencySids2; |
45 | 45 | ||
... | @@ -72,12 +72,12 @@ public class SegmentRoutingConfigTest { | ... | @@ -72,12 +72,12 @@ public class SegmentRoutingConfigTest { |
72 | adjacencySids2.put(300, ports3); | 72 | adjacencySids2.put(300, ports3); |
73 | 73 | ||
74 | DeviceId subject = DeviceId.deviceId("of:0000000000000001"); | 74 | DeviceId subject = DeviceId.deviceId("of:0000000000000001"); |
75 | - String key = "org.onosproject.segmentrouting"; | 75 | + String key = "segmentrouting"; |
76 | ObjectMapper mapper = new ObjectMapper(); | 76 | ObjectMapper mapper = new ObjectMapper(); |
77 | JsonNode jsonNode = mapper.readTree(jsonString); | 77 | JsonNode jsonNode = mapper.readTree(jsonString); |
78 | ConfigApplyDelegate delegate = new MockDelegate(); | 78 | ConfigApplyDelegate delegate = new MockDelegate(); |
79 | 79 | ||
80 | - config = new SegmentRoutingConfig(); | 80 | + config = new SegmentRoutingDeviceConfig(); |
81 | config.init(subject, key, jsonNode, mapper, delegate); | 81 | config.init(subject, key, jsonNode, mapper, delegate); |
82 | } | 82 | } |
83 | 83 | ... | ... |
... | @@ -44,8 +44,9 @@ public final class PortNumber { | ... | @@ -44,8 +44,9 @@ public final class PortNumber { |
44 | static final long NORMAL_NUMBER = -6L; | 44 | static final long NORMAL_NUMBER = -6L; |
45 | static final long FLOOD_NUMBER = -5L; | 45 | static final long FLOOD_NUMBER = -5L; |
46 | static final long ALL_NUMBER = -4L; | 46 | static final long ALL_NUMBER = -4L; |
47 | - static final long LOCAL_NUMBER = -2L; | ||
48 | static final long CONTROLLER_NUMBER = -3L; | 47 | static final long CONTROLLER_NUMBER = -3L; |
48 | + static final long LOCAL_NUMBER = -2L; | ||
49 | + static final long ANY_NUMBER = -1L; | ||
49 | 50 | ||
50 | /** | 51 | /** |
51 | * Logical PortNumbers. | 52 | * Logical PortNumbers. |
... | @@ -57,7 +58,8 @@ public final class PortNumber { | ... | @@ -57,7 +58,8 @@ public final class PortNumber { |
57 | FLOOD(FLOOD_NUMBER), | 58 | FLOOD(FLOOD_NUMBER), |
58 | ALL(ALL_NUMBER), | 59 | ALL(ALL_NUMBER), |
59 | LOCAL(LOCAL_NUMBER), | 60 | LOCAL(LOCAL_NUMBER), |
60 | - CONTROLLER(CONTROLLER_NUMBER); | 61 | + CONTROLLER(CONTROLLER_NUMBER), |
62 | + ANY(ANY_NUMBER); | ||
61 | 63 | ||
62 | private final long number; | 64 | private final long number; |
63 | private final PortNumber instance; | 65 | private final PortNumber instance; |
... | @@ -88,6 +90,7 @@ public final class PortNumber { | ... | @@ -88,6 +90,7 @@ public final class PortNumber { |
88 | public static final PortNumber ALL = new PortNumber(ALL_NUMBER); | 90 | public static final PortNumber ALL = new PortNumber(ALL_NUMBER); |
89 | public static final PortNumber LOCAL = new PortNumber(LOCAL_NUMBER); | 91 | public static final PortNumber LOCAL = new PortNumber(LOCAL_NUMBER); |
90 | public static final PortNumber CONTROLLER = new PortNumber(CONTROLLER_NUMBER); | 92 | public static final PortNumber CONTROLLER = new PortNumber(CONTROLLER_NUMBER); |
93 | + public static final PortNumber ANY = new PortNumber(ANY_NUMBER); | ||
91 | 94 | ||
92 | // lazily populated Logical port number to PortNumber | 95 | // lazily populated Logical port number to PortNumber |
93 | static final Supplier<Map<Long, Logical>> LOGICAL = Suppliers.memoize(() -> { | 96 | static final Supplier<Map<Long, Logical>> LOGICAL = Suppliers.memoize(() -> { | ... | ... |
... | @@ -25,6 +25,7 @@ import java.util.List; | ... | @@ -25,6 +25,7 @@ import java.util.List; |
25 | import java.util.Set; | 25 | import java.util.Set; |
26 | import java.util.concurrent.ConcurrentHashMap; | 26 | import java.util.concurrent.ConcurrentHashMap; |
27 | 27 | ||
28 | +import com.google.common.collect.ImmutableList; | ||
28 | import org.onlab.packet.Ethernet; | 29 | import org.onlab.packet.Ethernet; |
29 | import org.onlab.packet.MacAddress; | 30 | import org.onlab.packet.MacAddress; |
30 | import org.onlab.packet.IpPrefix; | 31 | import org.onlab.packet.IpPrefix; |
... | @@ -288,6 +289,11 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -288,6 +289,11 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
288 | VlanIdCriterion vidCriterion, | 289 | VlanIdCriterion vidCriterion, |
289 | VlanId assignedVlan, | 290 | VlanId assignedVlan, |
290 | ApplicationId applicationId) { | 291 | ApplicationId applicationId) { |
292 | + // Consider PortNumber.ANY as wildcard. Match ETH_DST only | ||
293 | + if (portCriterion != null && portCriterion.port() == PortNumber.ANY) { | ||
294 | + return processEthDstOnlyFilter(ethCriterion, applicationId); | ||
295 | + } | ||
296 | + | ||
291 | //handling untagged packets via assigned VLAN | 297 | //handling untagged packets via assigned VLAN |
292 | if (vidCriterion.vlanId() == VlanId.NONE) { | 298 | if (vidCriterion.vlanId() == VlanId.NONE) { |
293 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 299 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); |
... | @@ -354,6 +360,32 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -354,6 +360,32 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
354 | return rules; | 360 | return rules; |
355 | } | 361 | } |
356 | 362 | ||
363 | + @Override | ||
364 | + protected List<FlowRule> processEthDstOnlyFilter(EthCriterion ethCriterion, | ||
365 | + ApplicationId applicationId) { | ||
366 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
367 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
368 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
369 | + selector.matchEthDst(ethCriterion.mac()); | ||
370 | + /* | ||
371 | + * Note: CpqD switches do not handle MPLS-related operation properly | ||
372 | + * for a packet with VLAN tag. We pop VLAN here as a workaround. | ||
373 | + * Side effect: HostService learns redundant hosts with same MAC but | ||
374 | + * different VLAN. No known side effect on the network reachability. | ||
375 | + */ | ||
376 | + treatment.popVlan(); | ||
377 | + treatment.transition(UNICAST_ROUTING_TABLE); | ||
378 | + FlowRule rule = DefaultFlowRule.builder() | ||
379 | + .forDevice(deviceId) | ||
380 | + .withSelector(selector.build()) | ||
381 | + .withTreatment(treatment.build()) | ||
382 | + .withPriority(DEFAULT_PRIORITY) | ||
383 | + .fromApp(applicationId) | ||
384 | + .makePermanent() | ||
385 | + .forTable(TMAC_TABLE).build(); | ||
386 | + return ImmutableList.<FlowRule>builder().add(rule).build(); | ||
387 | + } | ||
388 | + | ||
357 | /* | 389 | /* |
358 | * Cpqd emulation allows MPLS ecmp. | 390 | * Cpqd emulation allows MPLS ecmp. |
359 | * | 391 | * |
... | @@ -600,6 +632,7 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -600,6 +632,7 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
600 | log.warn("Cannot process instruction in versatile fwd {}", ins); | 632 | log.warn("Cannot process instruction in versatile fwd {}", ins); |
601 | } | 633 | } |
602 | } | 634 | } |
635 | + ttBuilder.wipeDeferred(); | ||
603 | } | 636 | } |
604 | if (fwd.nextId() != null) { | 637 | if (fwd.nextId() != null) { |
605 | // overide case | 638 | // overide case | ... | ... |
... | @@ -78,6 +78,11 @@ public class CpqdOFDPA2VlanPipeline extends CpqdOFDPA2Pipeline { | ... | @@ -78,6 +78,11 @@ public class CpqdOFDPA2VlanPipeline extends CpqdOFDPA2Pipeline { |
78 | VlanIdCriterion vidCriterion, | 78 | VlanIdCriterion vidCriterion, |
79 | VlanId assignedVlan, | 79 | VlanId assignedVlan, |
80 | ApplicationId applicationId) { | 80 | ApplicationId applicationId) { |
81 | + // Consider PortNumber.ANY as wildcard. Match ETH_DST only | ||
82 | + if (portCriterion != null && portCriterion.port() == PortNumber.ANY) { | ||
83 | + return processEthDstOnlyFilter(ethCriterion, applicationId); | ||
84 | + } | ||
85 | + | ||
81 | //handling untagged packets via assigned VLAN | 86 | //handling untagged packets via assigned VLAN |
82 | if (vidCriterion.vlanId() == VlanId.NONE) { | 87 | if (vidCriterion.vlanId() == VlanId.NONE) { |
83 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 88 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | ... | ... |
... | @@ -6,6 +6,7 @@ import com.google.common.cache.CacheBuilder; | ... | @@ -6,6 +6,7 @@ import com.google.common.cache.CacheBuilder; |
6 | import com.google.common.cache.RemovalCause; | 6 | import com.google.common.cache.RemovalCause; |
7 | import com.google.common.cache.RemovalNotification; | 7 | import com.google.common.cache.RemovalNotification; |
8 | import org.onlab.osgi.ServiceDirectory; | 8 | import org.onlab.osgi.ServiceDirectory; |
9 | +import org.onlab.packet.MacAddress; | ||
9 | import org.onlab.packet.MplsLabel; | 10 | import org.onlab.packet.MplsLabel; |
10 | import org.onlab.packet.VlanId; | 11 | import org.onlab.packet.VlanId; |
11 | import org.onosproject.core.ApplicationId; | 12 | import org.onosproject.core.ApplicationId; |
... | @@ -95,7 +96,7 @@ public class OFDPA2GroupHandler { | ... | @@ -95,7 +96,7 @@ public class OFDPA2GroupHandler { |
95 | Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", "ofdpa2-%d")); | 96 | Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", "ofdpa2-%d")); |
96 | 97 | ||
97 | // index number for group creation | 98 | // index number for group creation |
98 | - private AtomicInteger l3vpnindex = new AtomicInteger(0); | 99 | + private AtomicInteger l3VpnIndex = new AtomicInteger(0); |
99 | 100 | ||
100 | // local stores for port-vlan mapping | 101 | // local stores for port-vlan mapping |
101 | protected Map<PortNumber, VlanId> port2Vlan = new ConcurrentHashMap<>(); | 102 | protected Map<PortNumber, VlanId> port2Vlan = new ConcurrentHashMap<>(); |
... | @@ -332,12 +333,14 @@ public class OFDPA2GroupHandler { | ... | @@ -332,12 +333,14 @@ public class OFDPA2GroupHandler { |
332 | VlanId vlanid = null; | 333 | VlanId vlanid = null; |
333 | long portNum = 0; | 334 | long portNum = 0; |
334 | boolean setVlan = false, popVlan = false; | 335 | boolean setVlan = false, popVlan = false; |
336 | + MacAddress dstMac = MacAddress.ZERO; | ||
335 | for (Instruction ins : treatment.allInstructions()) { | 337 | for (Instruction ins : treatment.allInstructions()) { |
336 | if (ins.type() == Instruction.Type.L2MODIFICATION) { | 338 | if (ins.type() == Instruction.Type.L2MODIFICATION) { |
337 | L2ModificationInstruction l2ins = (L2ModificationInstruction) ins; | 339 | L2ModificationInstruction l2ins = (L2ModificationInstruction) ins; |
338 | switch (l2ins.subtype()) { | 340 | switch (l2ins.subtype()) { |
339 | case ETH_DST: | 341 | case ETH_DST: |
340 | - outerTtb.setEthDst(((L2ModificationInstruction.ModEtherInstruction) l2ins).mac()); | 342 | + dstMac = ((L2ModificationInstruction.ModEtherInstruction) l2ins).mac(); |
343 | + outerTtb.setEthDst(dstMac); | ||
341 | break; | 344 | break; |
342 | case ETH_SRC: | 345 | case ETH_SRC: |
343 | outerTtb.setEthSrc(((L2ModificationInstruction.ModEtherInstruction) l2ins).mac()); | 346 | outerTtb.setEthSrc(((L2ModificationInstruction.ModEtherInstruction) l2ins).mac()); |
... | @@ -430,8 +433,11 @@ public class OFDPA2GroupHandler { | ... | @@ -430,8 +433,11 @@ public class OFDPA2GroupHandler { |
430 | mplsgroupkey, nextId); | 433 | mplsgroupkey, nextId); |
431 | } else { | 434 | } else { |
432 | // outer group is L3Unicast | 435 | // outer group is L3Unicast |
433 | - int l3groupId = L3_UNICAST_TYPE | (int) portNum; | 436 | + int l3groupId = L3_UNICAST_TYPE | |
434 | - int l3gk = L3_UNICAST_TYPE | (TYPE_MASK & (deviceId.hashCode() << 8 | (int) portNum)); | 437 | + (TYPE_MASK & (int) (dstMac.toLong() & 0xffff) << 6 | (int) portNum); |
438 | + int l3gk = L3_UNICAST_TYPE | | ||
439 | + (TYPE_MASK & (deviceId.hashCode() << 22 | | ||
440 | + (int) (dstMac.toLong() & 0xffff) << 6 | (int) portNum)); | ||
435 | final GroupKey l3groupkey = new DefaultGroupKey(OFDPA2Pipeline.appKryo.serialize(l3gk)); | 441 | final GroupKey l3groupkey = new DefaultGroupKey(OFDPA2Pipeline.appKryo.serialize(l3gk)); |
436 | outerTtb.group(new DefaultGroupId(l2groupId)); | 442 | outerTtb.group(new DefaultGroupId(l2groupId)); |
437 | // create the l3unicast group description to wait for the | 443 | // create the l3unicast group description to wait for the |
... | @@ -734,8 +740,8 @@ public class OFDPA2GroupHandler { | ... | @@ -734,8 +740,8 @@ public class OFDPA2GroupHandler { |
734 | onelabelGroupInfo.outerGrpDesc.givenGroupId())); | 740 | onelabelGroupInfo.outerGrpDesc.givenGroupId())); |
735 | GroupBucket l3vpnGrpBkt = | 741 | GroupBucket l3vpnGrpBkt = |
736 | DefaultGroupBucket.createIndirectGroupBucket(l3vpnTtb.build()); | 742 | DefaultGroupBucket.createIndirectGroupBucket(l3vpnTtb.build()); |
737 | - int l3vpngroupId = MPLS_L3VPN_SUBTYPE | l3vpnindex.incrementAndGet(); | 743 | + int l3vpngroupId = MPLS_L3VPN_SUBTYPE | l3VpnIndex.incrementAndGet(); |
738 | - int l3vpngk = MPLS_L3VPN_SUBTYPE | nextObj.id() << 12 | l3vpnindex.get(); | 744 | + int l3vpngk = MPLS_L3VPN_SUBTYPE | nextObj.id() << 12 | l3VpnIndex.get(); |
739 | GroupKey l3vpngroupkey = new DefaultGroupKey(OFDPA2Pipeline.appKryo.serialize(l3vpngk)); | 745 | GroupKey l3vpngroupkey = new DefaultGroupKey(OFDPA2Pipeline.appKryo.serialize(l3vpngk)); |
740 | GroupDescription l3vpnGroupDesc = | 746 | GroupDescription l3vpnGroupDesc = |
741 | new DefaultGroupDescription( | 747 | new DefaultGroupDescription( | ... | ... |
... | @@ -27,6 +27,7 @@ import java.util.Objects; | ... | @@ -27,6 +27,7 @@ import java.util.Objects; |
27 | import java.util.Set; | 27 | import java.util.Set; |
28 | import java.util.concurrent.ConcurrentHashMap; | 28 | import java.util.concurrent.ConcurrentHashMap; |
29 | 29 | ||
30 | +import com.google.common.collect.ImmutableList; | ||
30 | import org.onlab.osgi.ServiceDirectory; | 31 | import org.onlab.osgi.ServiceDirectory; |
31 | import org.onlab.packet.Ethernet; | 32 | import org.onlab.packet.Ethernet; |
32 | import org.onlab.packet.IpPrefix; | 33 | import org.onlab.packet.IpPrefix; |
... | @@ -553,6 +554,11 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -553,6 +554,11 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
553 | VlanIdCriterion vidCriterion, | 554 | VlanIdCriterion vidCriterion, |
554 | VlanId assignedVlan, | 555 | VlanId assignedVlan, |
555 | ApplicationId applicationId) { | 556 | ApplicationId applicationId) { |
557 | + // Consider PortNumber.ANY as wildcard. Match ETH_DST only | ||
558 | + if (portCriterion != null && portCriterion.port() == PortNumber.ANY) { | ||
559 | + return processEthDstOnlyFilter(ethCriterion, applicationId); | ||
560 | + } | ||
561 | + | ||
556 | //handling untagged packets via assigned VLAN | 562 | //handling untagged packets via assigned VLAN |
557 | if (vidCriterion.vlanId() == VlanId.NONE) { | 563 | if (vidCriterion.vlanId() == VlanId.NONE) { |
558 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 564 | vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); |
... | @@ -611,6 +617,24 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -611,6 +617,24 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline |
611 | return rules; | 617 | return rules; |
612 | } | 618 | } |
613 | 619 | ||
620 | + protected List<FlowRule> processEthDstOnlyFilter(EthCriterion ethCriterion, | ||
621 | + ApplicationId applicationId) { | ||
622 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
623 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
624 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
625 | + selector.matchEthDst(ethCriterion.mac()); | ||
626 | + treatment.transition(UNICAST_ROUTING_TABLE); | ||
627 | + FlowRule rule = DefaultFlowRule.builder() | ||
628 | + .forDevice(deviceId) | ||
629 | + .withSelector(selector.build()) | ||
630 | + .withTreatment(treatment.build()) | ||
631 | + .withPriority(DEFAULT_PRIORITY) | ||
632 | + .fromApp(applicationId) | ||
633 | + .makePermanent() | ||
634 | + .forTable(TMAC_TABLE).build(); | ||
635 | + return ImmutableList.<FlowRule>builder().add(rule).build(); | ||
636 | + } | ||
637 | + | ||
614 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { | 638 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { |
615 | switch (fwd.flag()) { | 639 | switch (fwd.flag()) { |
616 | case SPECIFIC: | 640 | case SPECIFIC: | ... | ... |
... | @@ -23,6 +23,7 @@ import com.google.common.cache.CacheBuilder; | ... | @@ -23,6 +23,7 @@ import com.google.common.cache.CacheBuilder; |
23 | import com.google.common.cache.RemovalCause; | 23 | import com.google.common.cache.RemovalCause; |
24 | import com.google.common.cache.RemovalNotification; | 24 | import com.google.common.cache.RemovalNotification; |
25 | 25 | ||
26 | +import com.google.common.collect.ImmutableList; | ||
26 | import org.onlab.osgi.ServiceDirectory; | 27 | import org.onlab.osgi.ServiceDirectory; |
27 | import org.onlab.packet.Ethernet; | 28 | import org.onlab.packet.Ethernet; |
28 | import org.onlab.packet.MacAddress; | 29 | import org.onlab.packet.MacAddress; |
... | @@ -504,6 +505,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -504,6 +505,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
504 | fwd.treatment().allInstructions().get(0).type() == Instruction.Type.OUTPUT) { | 505 | fwd.treatment().allInstructions().get(0).type() == Instruction.Type.OUTPUT) { |
505 | OutputInstruction o = (OutputInstruction) fwd.treatment().allInstructions().get(0); | 506 | OutputInstruction o = (OutputInstruction) fwd.treatment().allInstructions().get(0); |
506 | if (o.port() == PortNumber.CONTROLLER) { | 507 | if (o.port() == PortNumber.CONTROLLER) { |
508 | + treatmentBuilder.popVlan(); | ||
507 | treatmentBuilder.punt(); | 509 | treatmentBuilder.punt(); |
508 | } else { | 510 | } else { |
509 | treatmentBuilder.add(o); | 511 | treatmentBuilder.add(o); |
... | @@ -780,6 +782,10 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -780,6 +782,10 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
780 | FilteringObjective filt, | 782 | FilteringObjective filt, |
781 | VlanId assignedVlan, | 783 | VlanId assignedVlan, |
782 | ApplicationId applicationId) { | 784 | ApplicationId applicationId) { |
785 | + if (vlanIdCriterion == null) { | ||
786 | + return processEthDstOnlyFilter(ethCriterion, applicationId, filt.priority()); | ||
787 | + } | ||
788 | + | ||
783 | //handling untagged packets via assigned VLAN | 789 | //handling untagged packets via assigned VLAN |
784 | if (vlanIdCriterion.vlanId() == VlanId.NONE) { | 790 | if (vlanIdCriterion.vlanId() == VlanId.NONE) { |
785 | vlanIdCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 791 | vlanIdCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); |
... | @@ -823,6 +829,24 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -823,6 +829,24 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
823 | return rules; | 829 | return rules; |
824 | } | 830 | } |
825 | 831 | ||
832 | + protected List<FlowRule> processEthDstOnlyFilter(EthCriterion ethCriterion, | ||
833 | + ApplicationId applicationId, int priority) { | ||
834 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
835 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
836 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
837 | + selector.matchEthDst(ethCriterion.mac()); | ||
838 | + treatment.transition(TABLE_IPV4_UNICAST); | ||
839 | + FlowRule rule = DefaultFlowRule.builder() | ||
840 | + .forDevice(deviceId) | ||
841 | + .withSelector(selector.build()) | ||
842 | + .withTreatment(treatment.build()) | ||
843 | + .withPriority(priority) | ||
844 | + .fromApp(applicationId) | ||
845 | + .makePermanent() | ||
846 | + .forTable(TABLE_TMAC).build(); | ||
847 | + return ImmutableList.<FlowRule>builder().add(rule).build(); | ||
848 | + } | ||
849 | + | ||
826 | protected List<FlowRule> processVlanIdFilter(VlanIdCriterion vlanIdCriterion, | 850 | protected List<FlowRule> processVlanIdFilter(VlanIdCriterion vlanIdCriterion, |
827 | FilteringObjective filt, | 851 | FilteringObjective filt, |
828 | VlanId assignedVlan, | 852 | VlanId assignedVlan, | ... | ... |
1 | +{ | ||
2 | + "ports" : { | ||
3 | + "of:0000000000000001/3" : { | ||
4 | + "interfaces" : [ | ||
5 | + { | ||
6 | + "ips" : [ "10.0.1.254/24" ], | ||
7 | + "vlan" : "-1" | ||
8 | + } | ||
9 | + ] | ||
10 | + }, | ||
11 | + "of:0000000000000001/4" : { | ||
12 | + "interfaces" : [ | ||
13 | + { | ||
14 | + "ips" : [ "10.0.1.254/24", "200.0.0.200/32" ], | ||
15 | + "vlan" : "-1" | ||
16 | + } | ||
17 | + ] | ||
18 | + }, | ||
19 | + "of:0000000000000002/3" : { | ||
20 | + "interfaces" : [ | ||
21 | + { | ||
22 | + "ips" : [ "10.0.2.254/24" ], | ||
23 | + "vlan" : "-1" | ||
24 | + } | ||
25 | + ] | ||
26 | + }, | ||
27 | + "of:0000000000000002/4" : { | ||
28 | + "interfaces" : [ | ||
29 | + { | ||
30 | + "ips" : [ "10.0.2.254/24", "0.0.0.0/0" ], | ||
31 | + "vlan" : "-1" | ||
32 | + } | ||
33 | + ] | ||
34 | + } | ||
35 | + }, | ||
36 | + "devices" : { | ||
37 | + "of:0000000000000001" : { | ||
38 | + "segmentrouting" : { | ||
39 | + "name" : "Leaf-R1", | ||
40 | + "nodeSid" : 101, | ||
41 | + "routerIp" : "10.0.1.254", | ||
42 | + "routerMac" : "00:00:00:00:01:80", | ||
43 | + "isEdgeRouter" : true, | ||
44 | + "adjacencySids" : [] | ||
45 | + } | ||
46 | + }, | ||
47 | + "of:0000000000000002" : { | ||
48 | + "segmentrouting" : { | ||
49 | + "name" : "Leaf-R2", | ||
50 | + "nodeSid" : 102, | ||
51 | + "routerIp" : "10.0.2.254", | ||
52 | + "routerMac" : "00:00:00:00:02:80", | ||
53 | + "isEdgeRouter" : true, | ||
54 | + "adjacencySids" : [] | ||
55 | + } | ||
56 | + }, | ||
57 | + "of:0000000000000191" : { | ||
58 | + "segmentrouting" : { | ||
59 | + "name" : "Spine-R1", | ||
60 | + "nodeSid" : 103, | ||
61 | + "routerIp" : "192.168.0.11", | ||
62 | + "routerMac" : "00:00:01:00:11:80", | ||
63 | + "isEdgeRouter" : false, | ||
64 | + "adjacencySids" : [] | ||
65 | + } | ||
66 | + }, | ||
67 | + "of:0000000000000192" : { | ||
68 | + "segmentrouting" : { | ||
69 | + "name" : "Spine-R2", | ||
70 | + "nodeSid" : 104, | ||
71 | + "routerIp" : "192.168.0.22", | ||
72 | + "routerMac" : "00:00:01:00:22:80", | ||
73 | + "isEdgeRouter" : false, | ||
74 | + "adjacencySids" : [] | ||
75 | + } | ||
76 | + } | ||
77 | + }, | ||
78 | + "hosts" : { | ||
79 | + "00:00:00:00:00:01/-1" : { | ||
80 | + "basic": { | ||
81 | + "ips": ["10.0.1.1"], | ||
82 | + "location": "of:0000000000000001/3" | ||
83 | + } | ||
84 | + }, | ||
85 | + "00:00:00:00:00:02/-1" : { | ||
86 | + "basic": { | ||
87 | + "ips": ["10.0.1.2"], | ||
88 | + "location": "of:0000000000000001/4" | ||
89 | + } | ||
90 | + }, | ||
91 | + "00:00:00:00:00:03/-1" : { | ||
92 | + "basic": { | ||
93 | + "ips": ["10.0.2.1"], | ||
94 | + "location": "of:0000000000000002/3" | ||
95 | + } | ||
96 | + }, | ||
97 | + "00:00:00:00:00:04/-1" : { | ||
98 | + "basic": { | ||
99 | + "ips": ["10.0.2.2"], | ||
100 | + "location": "of:0000000000000002/4" | ||
101 | + } | ||
102 | + }, | ||
103 | + "00:00:00:aa:00:01/-1" : { | ||
104 | + "basic": { | ||
105 | + "ips": ["200.0.0.200"], | ||
106 | + "location": "of:0000000000000001/4" | ||
107 | + } | ||
108 | + } | ||
109 | + }, | ||
110 | + "apps" : { | ||
111 | + "org.onosproject.segmentrouting" : { | ||
112 | + "segmentrouting" : { | ||
113 | + "vRouterMacs" : [ | ||
114 | + "00:00:00:aa:00:02" | ||
115 | + ] | ||
116 | + } | ||
117 | + } | ||
118 | + } | ||
119 | +} |
... | @@ -86,25 +86,25 @@ | ... | @@ -86,25 +86,25 @@ |
86 | } | 86 | } |
87 | }, | 87 | }, |
88 | "hosts" : { | 88 | "hosts" : { |
89 | - "00:00:00:00:00:01/4093" : { | 89 | + "00:00:00:00:00:01/-1" : { |
90 | "basic": { | 90 | "basic": { |
91 | "ips": ["10.0.1.1"], | 91 | "ips": ["10.0.1.1"], |
92 | "location": "of:0000000000000001/3" | 92 | "location": "of:0000000000000001/3" |
93 | } | 93 | } |
94 | }, | 94 | }, |
95 | - "00:00:00:00:00:02/4093" : { | 95 | + "00:00:00:00:00:02/-1" : { |
96 | "basic": { | 96 | "basic": { |
97 | "ips": ["10.0.1.2"], | 97 | "ips": ["10.0.1.2"], |
98 | "location": "of:0000000000000001/4" | 98 | "location": "of:0000000000000001/4" |
99 | } | 99 | } |
100 | }, | 100 | }, |
101 | - "00:00:00:00:00:03/4093" : { | 101 | + "00:00:00:00:00:03/-1" : { |
102 | "basic": { | 102 | "basic": { |
103 | "ips": ["10.0.2.1"], | 103 | "ips": ["10.0.2.1"], |
104 | "location": "of:0000000000000002/3" | 104 | "location": "of:0000000000000002/3" |
105 | } | 105 | } |
106 | }, | 106 | }, |
107 | - "00:00:00:00:00:04/4093" : { | 107 | + "00:00:00:00:00:04/-1" : { |
108 | "basic": { | 108 | "basic": { |
109 | "ips": ["10.0.2.2"], | 109 | "ips": ["10.0.2.2"], |
110 | "location": "of:0000000000000002/4" | 110 | "location": "of:0000000000000002/4" | ... | ... |
... | @@ -148,49 +148,49 @@ | ... | @@ -148,49 +148,49 @@ |
148 | } | 148 | } |
149 | }, | 149 | }, |
150 | "hosts" : { | 150 | "hosts" : { |
151 | - "00:00:00:00:00:01/4093" : { | 151 | + "00:00:00:00:00:01/-1" : { |
152 | "basic": { | 152 | "basic": { |
153 | "ips": ["10.0.1.1"], | 153 | "ips": ["10.0.1.1"], |
154 | "location": "of:0000000000000001/5" | 154 | "location": "of:0000000000000001/5" |
155 | } | 155 | } |
156 | }, | 156 | }, |
157 | - "00:00:00:00:00:02/4093" : { | 157 | + "00:00:00:00:00:02/-1" : { |
158 | "basic": { | 158 | "basic": { |
159 | "ips": ["10.0.1.2"], | 159 | "ips": ["10.0.1.2"], |
160 | "location": "of:0000000000000001/6" | 160 | "location": "of:0000000000000001/6" |
161 | } | 161 | } |
162 | }, | 162 | }, |
163 | - "00:00:00:00:00:03/4093" : { | 163 | + "00:00:00:00:00:03/-1" : { |
164 | "basic": { | 164 | "basic": { |
165 | "ips": ["10.0.2.1"], | 165 | "ips": ["10.0.2.1"], |
166 | "location": "of:0000000000000002/5" | 166 | "location": "of:0000000000000002/5" |
167 | } | 167 | } |
168 | }, | 168 | }, |
169 | - "00:00:00:00:00:04/4093" : { | 169 | + "00:00:00:00:00:04/-1" : { |
170 | "basic": { | 170 | "basic": { |
171 | "ips": ["10.0.2.2"], | 171 | "ips": ["10.0.2.2"], |
172 | "location": "of:0000000000000002/6" | 172 | "location": "of:0000000000000002/6" |
173 | } | 173 | } |
174 | }, | 174 | }, |
175 | - "00:00:00:00:00:05/4093" : { | 175 | + "00:00:00:00:00:05/-1" : { |
176 | "basic": { | 176 | "basic": { |
177 | "ips": ["10.0.3.1"], | 177 | "ips": ["10.0.3.1"], |
178 | "location": "of:0000000000000003/5" | 178 | "location": "of:0000000000000003/5" |
179 | } | 179 | } |
180 | }, | 180 | }, |
181 | - "00:00:00:00:00:06/4093" : { | 181 | + "00:00:00:00:00:06/-1" : { |
182 | "basic": { | 182 | "basic": { |
183 | "ips": ["10.0.3.2"], | 183 | "ips": ["10.0.3.2"], |
184 | "location": "of:0000000000000003/6" | 184 | "location": "of:0000000000000003/6" |
185 | } | 185 | } |
186 | }, | 186 | }, |
187 | - "00:00:00:00:00:07/4093" : { | 187 | + "00:00:00:00:00:07/-1" : { |
188 | "basic": { | 188 | "basic": { |
189 | "ips": ["10.0.4.1"], | 189 | "ips": ["10.0.4.1"], |
190 | "location": "of:0000000000000004/5" | 190 | "location": "of:0000000000000004/5" |
191 | } | 191 | } |
192 | }, | 192 | }, |
193 | - "00:00:00:00:00:08/4093" : { | 193 | + "00:00:00:00:00:08/-1" : { |
194 | "basic": { | 194 | "basic": { |
195 | "ips": ["10.0.4.2"], | 195 | "ips": ["10.0.4.2"], |
196 | "location": "of:0000000000000004/6" | 196 | "location": "of:0000000000000004/6" | ... | ... |
-
Please register or login to post a comment