Charles Chan

CORD-60 Support dynamic vSG creation/deletion

We no longer need to configure /32 IP in interfaces.
SR will push a per-host route when discovering a host
with IP address(es) that does not belong to configured subnet.

Also includes:
- HostHandler refactoring

Change-Id: Ic1ad42d1ccdfee32be85f49e6fc94d9026000ffc
...@@ -15,11 +15,13 @@ ...@@ -15,11 +15,13 @@
15 */ 15 */
16 package org.onosproject.segmentrouting; 16 package org.onosproject.segmentrouting;
17 17
18 +import com.google.common.collect.ImmutableSet;
18 import com.google.common.collect.Maps; 19 import com.google.common.collect.Maps;
19 import com.google.common.collect.Sets; 20 import com.google.common.collect.Sets;
20 import org.onlab.packet.Ip4Address; 21 import org.onlab.packet.Ip4Address;
21 import org.onlab.packet.Ip4Prefix; 22 import org.onlab.packet.Ip4Prefix;
22 import org.onlab.packet.IpPrefix; 23 import org.onlab.packet.IpPrefix;
24 +import org.onosproject.net.ConnectPoint;
23 import org.onosproject.net.Device; 25 import org.onosproject.net.Device;
24 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
25 import org.onosproject.net.Link; 27 import org.onosproject.net.Link;
...@@ -45,9 +47,9 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -45,9 +47,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
45 * routing rule population. 47 * routing rule population.
46 */ 48 */
47 public class DefaultRoutingHandler { 49 public class DefaultRoutingHandler {
48 - 50 + private static final int MAX_RETRY_ATTEMPTS = 5;
49 - private static Logger log = LoggerFactory 51 + private static final String ECMPSPG_MISSING = "ECMP shortest path graph not found";
50 - .getLogger(DefaultRoutingHandler.class); 52 + private static Logger log = LoggerFactory.getLogger(DefaultRoutingHandler.class);
51 53
52 private SegmentRoutingManager srManager; 54 private SegmentRoutingManager srManager;
53 private RoutingRulePopulator rulePopulator; 55 private RoutingRulePopulator rulePopulator;
...@@ -56,7 +58,6 @@ public class DefaultRoutingHandler { ...@@ -56,7 +58,6 @@ public class DefaultRoutingHandler {
56 private DeviceConfiguration config; 58 private DeviceConfiguration config;
57 private final Lock statusLock = new ReentrantLock(); 59 private final Lock statusLock = new ReentrantLock();
58 private volatile Status populationStatus; 60 private volatile Status populationStatus;
59 - private static final int MAX_RETRY_ATTEMPTS = 5;
60 private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); 61 private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
61 62
62 /** 63 /**
...@@ -113,7 +114,7 @@ public class DefaultRoutingHandler { ...@@ -113,7 +114,7 @@ public class DefaultRoutingHandler {
113 } 114 }
114 115
115 EcmpShortestPathGraph ecmpSpg = new EcmpShortestPathGraph(sw.id(), srManager); 116 EcmpShortestPathGraph ecmpSpg = new EcmpShortestPathGraph(sw.id(), srManager);
116 - if (!populateEcmpRoutingRules(sw.id(), ecmpSpg)) { 117 + if (!populateEcmpRoutingRules(sw.id(), ecmpSpg, ImmutableSet.of())) {
117 log.debug("populateAllRoutingRules: populationStatus is ABORTED"); 118 log.debug("populateAllRoutingRules: populationStatus is ABORTED");
118 populationStatus = Status.ABORTED; 119 populationStatus = Status.ABORTED;
119 log.debug("Abort routing rule population"); 120 log.debug("Abort routing rule population");
...@@ -210,7 +211,7 @@ public class DefaultRoutingHandler { ...@@ -210,7 +211,7 @@ public class DefaultRoutingHandler {
210 if (link.size() == 1) { 211 if (link.size() == 1) {
211 log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", link.get(0)); 212 log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", link.get(0));
212 EcmpShortestPathGraph ecmpSpg = new EcmpShortestPathGraph(link.get(0), srManager); 213 EcmpShortestPathGraph ecmpSpg = new EcmpShortestPathGraph(link.get(0), srManager);
213 - if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { 214 + if (populateEcmpRoutingRules(link.get(0), ecmpSpg, ImmutableSet.of())) {
214 log.debug("Populating flow rules from {} to all is successful", 215 log.debug("Populating flow rules from {} to all is successful",
215 link.get(0)); 216 link.get(0));
216 currentEcmpSpgMap.put(link.get(0), ecmpSpg); 217 currentEcmpSpgMap.put(link.get(0), ecmpSpg);
...@@ -255,7 +256,8 @@ public class DefaultRoutingHandler { ...@@ -255,7 +256,8 @@ public class DefaultRoutingHandler {
255 nextHops.add(via.get(0)); 256 nextHops.add(via.get(0));
256 } 257 }
257 } 258 }
258 - if (!populateEcmpRoutingRulePartial(targetSw, dst, nextHops)) { 259 + if (!populateEcmpRoutingRulePartial(targetSw, dst,
260 + nextHops, ImmutableSet.of())) {
259 return false; 261 return false;
260 } 262 }
261 log.debug("Populating flow rules from {} to {} is successful", 263 log.debug("Populating flow rules from {} to {} is successful",
...@@ -422,8 +424,17 @@ public class DefaultRoutingHandler { ...@@ -422,8 +424,17 @@ public class DefaultRoutingHandler {
422 return subLinks; 424 return subLinks;
423 } 425 }
424 426
427 + /**
428 + * Populate ECMP rules for subnets from all switches to destination.
429 + *
430 + * @param destSw Device ID of destination switch
431 + * @param ecmpSPG ECMP shortest path graph
432 + * @param subnets Subnets to be populated. If empty, populate all configured subnets.
433 + * @return true if succeed
434 + */
425 private boolean populateEcmpRoutingRules(DeviceId destSw, 435 private boolean populateEcmpRoutingRules(DeviceId destSw,
426 - EcmpShortestPathGraph ecmpSPG) { 436 + EcmpShortestPathGraph ecmpSPG,
437 + Set<Ip4Prefix> subnets) {
427 438
428 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = ecmpSPG 439 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = ecmpSPG
429 .getAllLearnedSwitchesAndVia(); 440 .getAllLearnedSwitchesAndVia();
...@@ -440,7 +451,7 @@ public class DefaultRoutingHandler { ...@@ -440,7 +451,7 @@ public class DefaultRoutingHandler {
440 nextHops.add(via.get(0)); 451 nextHops.add(via.get(0));
441 } 452 }
442 } 453 }
443 - if (!populateEcmpRoutingRulePartial(targetSw, destSw, nextHops)) { 454 + if (!populateEcmpRoutingRulePartial(targetSw, destSw, nextHops, subnets)) {
444 return false; 455 return false;
445 } 456 }
446 } 457 }
...@@ -449,9 +460,19 @@ public class DefaultRoutingHandler { ...@@ -449,9 +460,19 @@ public class DefaultRoutingHandler {
449 return true; 460 return true;
450 } 461 }
451 462
463 + /**
464 + * Populate ECMP rules for subnets from target to destination via nexthops.
465 + *
466 + * @param targetSw Device ID of target switch
467 + * @param destSw Device ID of destination switch
468 + * @param nextHops List of next hops
469 + * @param subnets Subnets to be populated. If empty, populate all configured subnets.
470 + * @return true if succeed
471 + */
452 private boolean populateEcmpRoutingRulePartial(DeviceId targetSw, 472 private boolean populateEcmpRoutingRulePartial(DeviceId targetSw,
453 DeviceId destSw, 473 DeviceId destSw,
454 - Set<DeviceId> nextHops) { 474 + Set<DeviceId> nextHops,
475 + Set<Ip4Prefix> subnets) {
455 boolean result; 476 boolean result;
456 477
457 if (nextHops.isEmpty()) { 478 if (nextHops.isEmpty()) {
...@@ -473,13 +494,11 @@ public class DefaultRoutingHandler { ...@@ -473,13 +494,11 @@ public class DefaultRoutingHandler {
473 } 494 }
474 495
475 if (targetIsEdge && destIsEdge) { 496 if (targetIsEdge && destIsEdge) {
476 - Set<Ip4Prefix> subnets = config.getSubnets(destSw); 497 + subnets = (subnets != null && !subnets.isEmpty()) ? subnets : config.getSubnets(destSw);
477 log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}", 498 log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}",
478 targetSw, destSw, subnets); 499 targetSw, destSw, subnets);
479 - result = rulePopulator.populateIpRuleForSubnet(targetSw, 500 + result = rulePopulator.populateIpRuleForSubnet(targetSw, subnets,
480 - subnets, 501 + destSw, nextHops);
481 - destSw,
482 - nextHops);
483 if (!result) { 502 if (!result) {
484 return false; 503 return false;
485 } 504 }
...@@ -575,18 +594,54 @@ public class DefaultRoutingHandler { ...@@ -575,18 +594,54 @@ public class DefaultRoutingHandler {
575 } 594 }
576 } 595 }
577 596
578 - public void purgeEcmpGraph(DeviceId deviceId) { 597 + /**
598 + * Populate rules of given subnet at given location.
599 + *
600 + * @param cp connect point of the subnet being added
601 + * @param subnets subnet being added
602 + * @return true if succeed
603 + */
604 + protected boolean populateSubnet(ConnectPoint cp, Set<Ip4Prefix> subnets) {
605 + statusLock.lock();
606 + try {
607 + EcmpShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(cp.deviceId());
608 + if (ecmpSpg == null) {
609 + log.warn("Fail to populating subnet {}: {}", subnets, ECMPSPG_MISSING);
610 + return false;
611 + }
612 + return populateEcmpRoutingRules(cp.deviceId(), ecmpSpg, subnets);
613 + } finally {
614 + statusLock.unlock();
615 + }
616 + }
617 +
618 + /**
619 + * Revoke rules of given subnet at given location.
620 + *
621 + * @param subnets subnet being removed
622 + * @return true if succeed
623 + */
624 + protected boolean revokeSubnet(Set<Ip4Prefix> subnets) {
625 + statusLock.lock();
626 + try {
627 + return srManager.routingRulePopulator.revokeIpRuleForSubnet(subnets);
628 + } finally {
629 + statusLock.unlock();
630 + }
631 + }
632 +
633 + protected void purgeEcmpGraph(DeviceId deviceId) {
579 currentEcmpSpgMap.remove(deviceId); 634 currentEcmpSpgMap.remove(deviceId);
580 if (updatedEcmpSpgMap != null) { 635 if (updatedEcmpSpgMap != null) {
581 updatedEcmpSpgMap.remove(deviceId); 636 updatedEcmpSpgMap.remove(deviceId);
582 } 637 }
583 } 638 }
584 639
585 - private class RetryFilters implements Runnable { 640 + private final class RetryFilters implements Runnable {
586 int attempts = MAX_RETRY_ATTEMPTS; 641 int attempts = MAX_RETRY_ATTEMPTS;
587 DeviceId devId; 642 DeviceId devId;
588 643
589 - public RetryFilters(DeviceId deviceId) { 644 + private RetryFilters(DeviceId deviceId) {
590 devId = deviceId; 645 devId = deviceId;
591 } 646 }
592 647
......
...@@ -16,13 +16,15 @@ ...@@ -16,13 +16,15 @@
16 16
17 package org.onosproject.segmentrouting; 17 package org.onosproject.segmentrouting;
18 18
19 +import com.google.common.collect.ImmutableSet;
20 +import org.onlab.packet.Ip4Address;
19 import org.onlab.packet.Ip4Prefix; 21 import org.onlab.packet.Ip4Prefix;
20 import org.onlab.packet.IpAddress; 22 import org.onlab.packet.IpAddress;
21 import org.onlab.packet.MacAddress; 23 import org.onlab.packet.MacAddress;
22 import org.onlab.packet.VlanId; 24 import org.onlab.packet.VlanId;
23 -import org.onosproject.core.CoreService;
24 import org.onosproject.net.ConnectPoint; 25 import org.onosproject.net.ConnectPoint;
25 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
27 +import org.onosproject.net.HostLocation;
26 import org.onosproject.net.PortNumber; 28 import org.onosproject.net.PortNumber;
27 import org.onosproject.net.flow.DefaultTrafficSelector; 29 import org.onosproject.net.flow.DefaultTrafficSelector;
28 import org.onosproject.net.flow.DefaultTrafficTreatment; 30 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -46,7 +48,6 @@ import java.util.Set; ...@@ -46,7 +48,6 @@ import java.util.Set;
46 public class HostHandler { 48 public class HostHandler {
47 private static final Logger log = LoggerFactory.getLogger(HostHandler.class); 49 private static final Logger log = LoggerFactory.getLogger(HostHandler.class);
48 private final SegmentRoutingManager srManager; 50 private final SegmentRoutingManager srManager;
49 - private CoreService coreService;
50 private HostService hostService; 51 private HostService hostService;
51 private FlowObjectiveService flowObjectiveService; 52 private FlowObjectiveService flowObjectiveService;
52 53
...@@ -57,7 +58,6 @@ public class HostHandler { ...@@ -57,7 +58,6 @@ public class HostHandler {
57 */ 58 */
58 public HostHandler(SegmentRoutingManager srManager) { 59 public HostHandler(SegmentRoutingManager srManager) {
59 this.srManager = srManager; 60 this.srManager = srManager;
60 - coreService = srManager.coreService;
61 hostService = srManager.hostService; 61 hostService = srManager.hostService;
62 flowObjectiveService = srManager.flowObjectiveService; 62 flowObjectiveService = srManager.flowObjectiveService;
63 } 63 }
...@@ -65,116 +65,46 @@ public class HostHandler { ...@@ -65,116 +65,46 @@ public class HostHandler {
65 protected void readInitialHosts(DeviceId devId) { 65 protected void readInitialHosts(DeviceId devId) {
66 hostService.getHosts().forEach(host -> { 66 hostService.getHosts().forEach(host -> {
67 DeviceId deviceId = host.location().deviceId(); 67 DeviceId deviceId = host.location().deviceId();
68 + // The host does not attach to this device
68 if (!deviceId.equals(devId)) { 69 if (!deviceId.equals(devId)) {
69 - // not an attached host to this device
70 return; 70 return;
71 } 71 }
72 - MacAddress mac = host.mac(); 72 + processHostAddedEventInternal(host.mac(), host.vlan(),
73 - VlanId vlanId = host.vlan(); 73 + host.location(), host.ipAddresses());
74 - PortNumber port = host.location().port();
75 - Set<IpAddress> ips = host.ipAddresses();
76 - log.debug("Attached Host {}/{} is added at {}:{}", mac, vlanId,
77 - deviceId, port);
78 -
79 - // Populate bridging table entry
80 - ForwardingObjective.Builder fob =
81 - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port);
82 - if (fob == null) {
83 - log.warn("Aborting host bridging & routing table entries due "
84 - + "to error for dev:{} host:{}", deviceId, host);
85 - return;
86 - }
87 - ObjectiveContext context = new DefaultObjectiveContext(
88 - (objective) -> log.debug("Host rule for {} populated", host),
89 - (objective, error) ->
90 - log.warn("Failed to populate host rule for {}: {}", host, error));
91 - flowObjectiveService.forward(deviceId, fob.add(context));
92 -
93 - // Populate IP table entry
94 - ips.forEach(ip -> {
95 - if (ip.isIp4()) {
96 - srManager.routingRulePopulator.populateIpRuleForHost(
97 - deviceId, ip.getIp4Address(), mac, port);
98 - }
99 - });
100 }); 74 });
101 } 75 }
102 76
103 - private ForwardingObjective.Builder getForwardingObjectiveBuilder( 77 + protected void processHostAddedEvent(HostEvent event) {
104 - DeviceId deviceId, MacAddress mac, VlanId vlanId, 78 + processHostAddedEventInternal(event.subject().mac(), event.subject().vlan(),
105 - PortNumber outport) { 79 + event.subject().location(), event.subject().ipAddresses());
106 - // Get assigned VLAN for the subnet
107 - VlanId outvlan = null;
108 - Ip4Prefix subnet = srManager.deviceConfiguration.getPortSubnet(deviceId, outport);
109 - if (subnet == null) {
110 - outvlan = VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET);
111 - } else {
112 - outvlan = srManager.getSubnetAssignedVlanId(deviceId, subnet);
113 - }
114 -
115 - // match rule
116 - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
117 - sbuilder.matchEthDst(mac);
118 - /*
119 - * Note: for untagged packets, match on the assigned VLAN.
120 - * for tagged packets, match on its incoming VLAN.
121 - */
122 - if (vlanId.equals(VlanId.NONE)) {
123 - sbuilder.matchVlanId(outvlan);
124 - } else {
125 - sbuilder.matchVlanId(vlanId);
126 - }
127 -
128 - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
129 - tbuilder.immediate().popVlan();
130 - tbuilder.immediate().setOutput(outport);
131 -
132 - // for switch pipelines that need it, provide outgoing vlan as metadata
133 - TrafficSelector meta = DefaultTrafficSelector.builder()
134 - .matchVlanId(outvlan).build();
135 -
136 - // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed.
137 - int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outport,
138 - tbuilder.build(),
139 - meta);
140 - if (portNextObjId == -1) {
141 - // warning log will come from getPortNextObjective method
142 - return null;
143 - }
144 -
145 - return DefaultForwardingObjective.builder()
146 - .withFlag(ForwardingObjective.Flag.SPECIFIC)
147 - .withSelector(sbuilder.build())
148 - .nextStep(portNextObjId)
149 - .withPriority(100)
150 - .fromApp(srManager.appId)
151 - .makePermanent();
152 } 80 }
153 81
154 - protected void processHostAddedEvent(HostEvent event) { 82 + private void processHostAddedEventInternal(MacAddress mac, VlanId vlanId,
155 - MacAddress mac = event.subject().mac(); 83 + HostLocation location, Set<IpAddress> ips) {
156 - VlanId vlanId = event.subject().vlan(); 84 + DeviceId deviceId = location.deviceId();
157 - DeviceId deviceId = event.subject().location().deviceId(); 85 + PortNumber port = location.port();
158 - PortNumber port = event.subject().location().port();
159 - Set<IpAddress> ips = event.subject().ipAddresses();
160 log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); 86 log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port);
161 87
162 - if (!srManager.deviceConfiguration.suppressHost() 88 + if (!srManager.deviceConfiguration.suppressHost().contains(location)) {
163 - .contains(new ConnectPoint(deviceId, port))) {
164 // Populate bridging table entry 89 // Populate bridging table entry
165 log.debug("Populate L2 table entry for host {} at {}:{}", 90 log.debug("Populate L2 table entry for host {} at {}:{}",
166 mac, deviceId, port); 91 mac, deviceId, port);
167 ForwardingObjective.Builder fob = 92 ForwardingObjective.Builder fob =
168 - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); 93 + hostFwdObjBuilder(deviceId, mac, vlanId, port);
94 + if (fob == null) {
95 + log.warn("Fail to create fwd obj for host {}/{}. Abort.", mac, vlanId);
96 + return;
97 + }
169 ObjectiveContext context = new DefaultObjectiveContext( 98 ObjectiveContext context = new DefaultObjectiveContext(
170 - (objective) -> log.debug("Host rule for {} populated", event.subject()), 99 + (objective) -> log.debug("Host rule for {}/{} populated", mac, vlanId),
171 (objective, error) -> 100 (objective, error) ->
172 - log.warn("Failed to populate host rule for {}: {}", event.subject(), error)); 101 + log.warn("Failed to populate host rule for {}/{}: {}", mac, vlanId, error));
173 flowObjectiveService.forward(deviceId, fob.add(context)); 102 flowObjectiveService.forward(deviceId, fob.add(context));
174 103
175 - // Populate IP table entry
176 ips.forEach(ip -> { 104 ips.forEach(ip -> {
105 + // Populate IP table entry
177 if (ip.isIp4()) { 106 if (ip.isIp4()) {
107 + addPerHostRoute(location, ip.getIp4Address());
178 srManager.routingRulePopulator.populateIpRuleForHost( 108 srManager.routingRulePopulator.populateIpRuleForHost(
179 deviceId, ip.getIp4Address(), mac, port); 109 deviceId, ip.getIp4Address(), mac, port);
180 } 110 }
...@@ -185,8 +115,9 @@ public class HostHandler { ...@@ -185,8 +115,9 @@ public class HostHandler {
185 protected void processHostRemoveEvent(HostEvent event) { 115 protected void processHostRemoveEvent(HostEvent event) {
186 MacAddress mac = event.subject().mac(); 116 MacAddress mac = event.subject().mac();
187 VlanId vlanId = event.subject().vlan(); 117 VlanId vlanId = event.subject().vlan();
188 - DeviceId deviceId = event.subject().location().deviceId(); 118 + HostLocation location = event.subject().location();
189 - PortNumber port = event.subject().location().port(); 119 + DeviceId deviceId = location.deviceId();
120 + PortNumber port = location.port();
190 Set<IpAddress> ips = event.subject().ipAddresses(); 121 Set<IpAddress> ips = event.subject().ipAddresses();
191 log.debug("Host {}/{} is removed from {}:{}", mac, vlanId, deviceId, port); 122 log.debug("Host {}/{} is removed from {}:{}", mac, vlanId, deviceId, port);
192 123
...@@ -194,7 +125,11 @@ public class HostHandler { ...@@ -194,7 +125,11 @@ public class HostHandler {
194 .contains(new ConnectPoint(deviceId, port))) { 125 .contains(new ConnectPoint(deviceId, port))) {
195 // Revoke bridging table entry 126 // Revoke bridging table entry
196 ForwardingObjective.Builder fob = 127 ForwardingObjective.Builder fob =
197 - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); 128 + hostFwdObjBuilder(deviceId, mac, vlanId, port);
129 + if (fob == null) {
130 + log.warn("Fail to create fwd obj for host {}/{}. Abort.", mac, vlanId);
131 + return;
132 + }
198 ObjectiveContext context = new DefaultObjectiveContext( 133 ObjectiveContext context = new DefaultObjectiveContext(
199 (objective) -> log.debug("Host rule for {} revoked", event.subject()), 134 (objective) -> log.debug("Host rule for {} revoked", event.subject()),
200 (objective, error) -> 135 (objective, error) ->
...@@ -204,6 +139,7 @@ public class HostHandler { ...@@ -204,6 +139,7 @@ public class HostHandler {
204 // Revoke IP table entry 139 // Revoke IP table entry
205 ips.forEach(ip -> { 140 ips.forEach(ip -> {
206 if (ip.isIp4()) { 141 if (ip.isIp4()) {
142 + removePerHostRoute(location, ip.getIp4Address());
207 srManager.routingRulePopulator.revokeIpRuleForHost( 143 srManager.routingRulePopulator.revokeIpRuleForHost(
208 deviceId, ip.getIp4Address(), mac, port); 144 deviceId, ip.getIp4Address(), mac, port);
209 } 145 }
...@@ -214,11 +150,13 @@ public class HostHandler { ...@@ -214,11 +150,13 @@ public class HostHandler {
214 protected void processHostMovedEvent(HostEvent event) { 150 protected void processHostMovedEvent(HostEvent event) {
215 MacAddress mac = event.subject().mac(); 151 MacAddress mac = event.subject().mac();
216 VlanId vlanId = event.subject().vlan(); 152 VlanId vlanId = event.subject().vlan();
217 - DeviceId prevDeviceId = event.prevSubject().location().deviceId(); 153 + HostLocation prevLocation = event.prevSubject().location();
218 - PortNumber prevPort = event.prevSubject().location().port(); 154 + DeviceId prevDeviceId = prevLocation.deviceId();
155 + PortNumber prevPort = prevLocation.port();
219 Set<IpAddress> prevIps = event.prevSubject().ipAddresses(); 156 Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
220 - DeviceId newDeviceId = event.subject().location().deviceId(); 157 + HostLocation newLocation = event.subject().location();
221 - PortNumber newPort = event.subject().location().port(); 158 + DeviceId newDeviceId = newLocation.deviceId();
159 + PortNumber newPort = newLocation.port();
222 Set<IpAddress> newIps = event.subject().ipAddresses(); 160 Set<IpAddress> newIps = event.subject().ipAddresses();
223 log.debug("Host {}/{} is moved from {}:{} to {}:{}", 161 log.debug("Host {}/{} is moved from {}:{} to {}:{}",
224 mac, vlanId, prevDeviceId, prevPort, newDeviceId, newPort); 162 mac, vlanId, prevDeviceId, prevPort, newDeviceId, newPort);
...@@ -227,7 +165,11 @@ public class HostHandler { ...@@ -227,7 +165,11 @@ public class HostHandler {
227 .contains(new ConnectPoint(prevDeviceId, prevPort))) { 165 .contains(new ConnectPoint(prevDeviceId, prevPort))) {
228 // Revoke previous bridging table entry 166 // Revoke previous bridging table entry
229 ForwardingObjective.Builder prevFob = 167 ForwardingObjective.Builder prevFob =
230 - getForwardingObjectiveBuilder(prevDeviceId, mac, vlanId, prevPort); 168 + hostFwdObjBuilder(prevDeviceId, mac, vlanId, prevPort);
169 + if (prevFob == null) {
170 + log.warn("Fail to create fwd obj for host {}/{}. Abort.", mac, vlanId);
171 + return;
172 + }
231 ObjectiveContext context = new DefaultObjectiveContext( 173 ObjectiveContext context = new DefaultObjectiveContext(
232 (objective) -> log.debug("Host rule for {} revoked", event.subject()), 174 (objective) -> log.debug("Host rule for {} revoked", event.subject()),
233 (objective, error) -> 175 (objective, error) ->
...@@ -237,6 +179,7 @@ public class HostHandler { ...@@ -237,6 +179,7 @@ public class HostHandler {
237 // Revoke previous IP table entry 179 // Revoke previous IP table entry
238 prevIps.forEach(ip -> { 180 prevIps.forEach(ip -> {
239 if (ip.isIp4()) { 181 if (ip.isIp4()) {
182 + removePerHostRoute(prevLocation, ip.getIp4Address());
240 srManager.routingRulePopulator.revokeIpRuleForHost( 183 srManager.routingRulePopulator.revokeIpRuleForHost(
241 prevDeviceId, ip.getIp4Address(), mac, prevPort); 184 prevDeviceId, ip.getIp4Address(), mac, prevPort);
242 } 185 }
...@@ -247,7 +190,11 @@ public class HostHandler { ...@@ -247,7 +190,11 @@ public class HostHandler {
247 .contains(new ConnectPoint(newDeviceId, newPort))) { 190 .contains(new ConnectPoint(newDeviceId, newPort))) {
248 // Populate new bridging table entry 191 // Populate new bridging table entry
249 ForwardingObjective.Builder newFob = 192 ForwardingObjective.Builder newFob =
250 - getForwardingObjectiveBuilder(newDeviceId, mac, vlanId, newPort); 193 + hostFwdObjBuilder(newDeviceId, mac, vlanId, newPort);
194 + if (newFob == null) {
195 + log.warn("Fail to create fwd obj for host {}/{}. Abort.", mac, vlanId);
196 + return;
197 + }
251 ObjectiveContext context = new DefaultObjectiveContext( 198 ObjectiveContext context = new DefaultObjectiveContext(
252 (objective) -> log.debug("Host rule for {} populated", event.subject()), 199 (objective) -> log.debug("Host rule for {} populated", event.subject()),
253 (objective, error) -> 200 (objective, error) ->
...@@ -257,6 +204,7 @@ public class HostHandler { ...@@ -257,6 +204,7 @@ public class HostHandler {
257 // Populate new IP table entry 204 // Populate new IP table entry
258 newIps.forEach(ip -> { 205 newIps.forEach(ip -> {
259 if (ip.isIp4()) { 206 if (ip.isIp4()) {
207 + addPerHostRoute(newLocation, ip.getIp4Address());
260 srManager.routingRulePopulator.populateIpRuleForHost( 208 srManager.routingRulePopulator.populateIpRuleForHost(
261 newDeviceId, ip.getIp4Address(), mac, newPort); 209 newDeviceId, ip.getIp4Address(), mac, newPort);
262 } 210 }
...@@ -267,11 +215,13 @@ public class HostHandler { ...@@ -267,11 +215,13 @@ public class HostHandler {
267 protected void processHostUpdatedEvent(HostEvent event) { 215 protected void processHostUpdatedEvent(HostEvent event) {
268 MacAddress mac = event.subject().mac(); 216 MacAddress mac = event.subject().mac();
269 VlanId vlanId = event.subject().vlan(); 217 VlanId vlanId = event.subject().vlan();
270 - DeviceId prevDeviceId = event.prevSubject().location().deviceId(); 218 + HostLocation prevLocation = event.prevSubject().location();
271 - PortNumber prevPort = event.prevSubject().location().port(); 219 + DeviceId prevDeviceId = prevLocation.deviceId();
220 + PortNumber prevPort = prevLocation.port();
272 Set<IpAddress> prevIps = event.prevSubject().ipAddresses(); 221 Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
273 - DeviceId newDeviceId = event.subject().location().deviceId(); 222 + HostLocation newLocation = event.subject().location();
274 - PortNumber newPort = event.subject().location().port(); 223 + DeviceId newDeviceId = newLocation.deviceId();
224 + PortNumber newPort = newLocation.port();
275 Set<IpAddress> newIps = event.subject().ipAddresses(); 225 Set<IpAddress> newIps = event.subject().ipAddresses();
276 log.debug("Host {}/{} is updated", mac, vlanId); 226 log.debug("Host {}/{} is updated", mac, vlanId);
277 227
...@@ -280,6 +230,7 @@ public class HostHandler { ...@@ -280,6 +230,7 @@ public class HostHandler {
280 // Revoke previous IP table entry 230 // Revoke previous IP table entry
281 prevIps.forEach(ip -> { 231 prevIps.forEach(ip -> {
282 if (ip.isIp4()) { 232 if (ip.isIp4()) {
233 + removePerHostRoute(prevLocation, ip.getIp4Address());
283 srManager.routingRulePopulator.revokeIpRuleForHost( 234 srManager.routingRulePopulator.revokeIpRuleForHost(
284 prevDeviceId, ip.getIp4Address(), mac, prevPort); 235 prevDeviceId, ip.getIp4Address(), mac, prevPort);
285 } 236 }
...@@ -291,10 +242,106 @@ public class HostHandler { ...@@ -291,10 +242,106 @@ public class HostHandler {
291 // Populate new IP table entry 242 // Populate new IP table entry
292 newIps.forEach(ip -> { 243 newIps.forEach(ip -> {
293 if (ip.isIp4()) { 244 if (ip.isIp4()) {
245 + addPerHostRoute(newLocation, ip.getIp4Address());
294 srManager.routingRulePopulator.populateIpRuleForHost( 246 srManager.routingRulePopulator.populateIpRuleForHost(
295 newDeviceId, ip.getIp4Address(), mac, newPort); 247 newDeviceId, ip.getIp4Address(), mac, newPort);
296 } 248 }
297 }); 249 });
298 } 250 }
299 } 251 }
252 +
253 + /**
254 + * Generates the forwarding objective builder for the host rules.
255 + *
256 + * @param deviceId Device that host attaches to
257 + * @param mac MAC address of the host
258 + * @param vlanId VLAN ID of the host
259 + * @param outport Port that host attaches to
260 + * @return Forwarding objective builder
261 + */
262 + private ForwardingObjective.Builder hostFwdObjBuilder(
263 + DeviceId deviceId, MacAddress mac, VlanId vlanId,
264 + PortNumber outport) {
265 + // Get assigned VLAN for the subnets
266 + VlanId outvlan = null;
267 + Ip4Prefix subnet = srManager.deviceConfiguration.getPortSubnet(deviceId, outport);
268 + if (subnet == null) {
269 + outvlan = VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET);
270 + } else {
271 + outvlan = srManager.getSubnetAssignedVlanId(deviceId, subnet);
272 + }
273 +
274 + // match rule
275 + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
276 + sbuilder.matchEthDst(mac);
277 + /*
278 + * Note: for untagged packets, match on the assigned VLAN.
279 + * for tagged packets, match on its incoming VLAN.
280 + */
281 + if (vlanId.equals(VlanId.NONE)) {
282 + sbuilder.matchVlanId(outvlan);
283 + } else {
284 + sbuilder.matchVlanId(vlanId);
285 + }
286 +
287 + TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
288 + tbuilder.immediate().popVlan();
289 + tbuilder.immediate().setOutput(outport);
290 +
291 + // for switch pipelines that need it, provide outgoing vlan as metadata
292 + TrafficSelector meta = DefaultTrafficSelector.builder()
293 + .matchVlanId(outvlan).build();
294 +
295 + // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed.
296 + int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outport,
297 + tbuilder.build(),
298 + meta);
299 + if (portNextObjId == -1) {
300 + // warning log will come from getPortNextObjective method
301 + return null;
302 + }
303 +
304 + return DefaultForwardingObjective.builder()
305 + .withFlag(ForwardingObjective.Flag.SPECIFIC)
306 + .withSelector(sbuilder.build())
307 + .nextStep(portNextObjId)
308 + .withPriority(100)
309 + .fromApp(srManager.appId)
310 + .makePermanent();
311 + }
312 +
313 + /**
314 + * Add per host route to subnet list and populate the flow rule if the host
315 + * does not belong to the configured subnet.
316 + *
317 + * @param location location of the host being added
318 + * @param ip IP address of the host being added
319 + */
320 + private void addPerHostRoute(ConnectPoint location, Ip4Address ip) {
321 + Ip4Prefix portSubnet = srManager.deviceConfiguration.getPortSubnet(
322 + location.deviceId(), location.port());
323 + if (portSubnet != null && !portSubnet.contains(ip)) {
324 + Ip4Prefix ip4Prefix = ip.toIpPrefix().getIp4Prefix();
325 + srManager.deviceConfiguration.addSubnet(location, ip4Prefix);
326 + srManager.defaultRoutingHandler.populateSubnet(location,
327 + ImmutableSet.of(ip4Prefix));
328 + }
329 + }
330 +
331 + /**
332 + * Remove per host route from subnet list and revoke the flow rule if the
333 + * host does not belong to the configured subnet.
334 + *
335 + * @param location location of the host being removed
336 + * @param ip IP address of the host being removed
337 + */
338 + private void removePerHostRoute(ConnectPoint location, Ip4Address ip) {
339 + Ip4Prefix portSubnet = srManager.deviceConfiguration.getPortSubnet(
340 + location.deviceId(), location.port());
341 + if (portSubnet != null && !portSubnet.contains(ip)) {
342 + Ip4Prefix ip4Prefix = ip.toIpPrefix().getIp4Prefix();
343 + srManager.deviceConfiguration.removeSubnet(location, ip4Prefix);
344 + srManager.defaultRoutingHandler.revokeSubnet(ImmutableSet.of(ip4Prefix));
345 + }
346 + }
300 } 347 }
......
...@@ -212,22 +212,33 @@ public class RoutingRulePopulator { ...@@ -212,22 +212,33 @@ public class RoutingRulePopulator {
212 * Populates IP flow rules for the subnets of the destination router. 212 * Populates IP flow rules for the subnets of the destination router.
213 * 213 *
214 * @param deviceId switch ID to set the rules 214 * @param deviceId switch ID to set the rules
215 - * @param subnets subnet information 215 + * @param subnets subnet being added
216 * @param destSw destination switch ID 216 * @param destSw destination switch ID
217 * @param nextHops next hop switch ID list 217 * @param nextHops next hop switch ID list
218 * @return true if all rules are set successfully, false otherwise 218 * @return true if all rules are set successfully, false otherwise
219 */ 219 */
220 - public boolean populateIpRuleForSubnet(DeviceId deviceId, 220 + public boolean populateIpRuleForSubnet(DeviceId deviceId, Set<Ip4Prefix> subnets,
221 - Set<Ip4Prefix> subnets, 221 + DeviceId destSw, Set<DeviceId> nextHops) {
222 - DeviceId destSw,
223 - Set<DeviceId> nextHops) {
224 -
225 for (IpPrefix subnet : subnets) { 222 for (IpPrefix subnet : subnets) {
226 if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) { 223 if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) {
227 return false; 224 return false;
228 } 225 }
229 } 226 }
227 + return true;
228 + }
230 229
230 + /**
231 + * Revokes IP flow rules for the subnets.
232 + *
233 + * @param subnets subnet being removed
234 + * @return true if all rules are removed successfully, false otherwise
235 + */
236 + public boolean revokeIpRuleForSubnet(Set<Ip4Prefix> subnets) {
237 + for (IpPrefix subnet : subnets) {
238 + if (!revokeIpRuleForRouter(subnet)) {
239 + return false;
240 + }
241 + }
231 return true; 242 return true;
232 } 243 }
233 244
...@@ -310,6 +321,40 @@ public class RoutingRulePopulator { ...@@ -310,6 +321,40 @@ public class RoutingRulePopulator {
310 } 321 }
311 322
312 /** 323 /**
324 + * Revokes IP flow rules for the router IP address.
325 + *
326 + * @param ipPrefix the IP address of the destination router
327 + * @return true if all rules are removed successfully, false otherwise
328 + */
329 + public boolean revokeIpRuleForRouter(IpPrefix ipPrefix) {
330 + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
331 + sbuilder.matchIPDst(ipPrefix);
332 + sbuilder.matchEthType(Ethernet.TYPE_IPV4);
333 + TrafficSelector selector = sbuilder.build();
334 + TrafficTreatment dummyTreatment = DefaultTrafficTreatment.builder().build();
335 +
336 + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
337 + .builder()
338 + .fromApp(srManager.appId)
339 + .makePermanent()
340 + .withSelector(selector)
341 + .withTreatment(dummyTreatment)
342 + .withPriority(getPriorityFromPrefix(ipPrefix))
343 + .withFlag(ForwardingObjective.Flag.SPECIFIC);
344 +
345 + ObjectiveContext context = new DefaultObjectiveContext(
346 + (objective) -> log.debug("IP rule for router {} revoked", ipPrefix),
347 + (objective, error) ->
348 + log.warn("Failed to revoke IP rule for router {}: {}", ipPrefix, error));
349 +
350 + srManager.deviceService.getAvailableDevices().forEach(device -> {
351 + srManager.flowObjectiveService.forward(device.id(), fwdBuilder.remove(context));
352 + });
353 +
354 + return true;
355 + }
356 +
357 + /**
313 * Populates MPLS flow rules to all routers. 358 * Populates MPLS flow rules to all routers.
314 * 359 *
315 * @param deviceId target device ID of the switch to set the rules 360 * @param deviceId target device ID of the switch to set the rules
...@@ -471,6 +516,7 @@ public class RoutingRulePopulator { ...@@ -471,6 +516,7 @@ public class RoutingRulePopulator {
471 * that drivers can obtain other information (like Router MAC and IP). 516 * that drivers can obtain other information (like Router MAC and IP).
472 * 517 *
473 * @param deviceId the switch dpid for the router 518 * @param deviceId the switch dpid for the router
519 + * @return true if operation succeeds
474 */ 520 */
475 public boolean populateRouterMacVlanFilters(DeviceId deviceId) { 521 public boolean populateRouterMacVlanFilters(DeviceId deviceId) {
476 log.debug("Installing per-port filtering objective for untagged " 522 log.debug("Installing per-port filtering objective for untagged "
......
...@@ -153,7 +153,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -153,7 +153,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
153 protected ApplicationId appId; 153 protected ApplicationId appId;
154 protected DeviceConfiguration deviceConfiguration = null; 154 protected DeviceConfiguration deviceConfiguration = null;
155 155
156 - private DefaultRoutingHandler defaultRoutingHandler = null; 156 + protected DefaultRoutingHandler defaultRoutingHandler = null;
157 private TunnelHandler tunnelHandler = null; 157 private TunnelHandler tunnelHandler = null;
158 private PolicyHandler policyHandler = null; 158 private PolicyHandler policyHandler = null;
159 private InternalPacketProcessor processor = null; 159 private InternalPacketProcessor processor = null;
......
...@@ -46,6 +46,8 @@ import java.util.Optional; ...@@ -46,6 +46,8 @@ import java.util.Optional;
46 import java.util.Set; 46 import java.util.Set;
47 import java.util.concurrent.ConcurrentHashMap; 47 import java.util.concurrent.ConcurrentHashMap;
48 48
49 +import static com.google.common.base.Preconditions.checkNotNull;
50 +
49 /** 51 /**
50 * Segment Routing configuration component that reads the 52 * Segment Routing configuration component that reads the
51 * segment routing related configuration from Network Configuration Manager 53 * segment routing related configuration from Network Configuration Manager
...@@ -167,7 +169,6 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -167,7 +169,6 @@ public class DeviceConfiguration implements DeviceProperties {
167 } 169 }
168 } 170 }
169 }); 171 });
170 -
171 }); 172 });
172 } 173 }
173 174
...@@ -517,4 +518,38 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -517,4 +518,38 @@ public class DeviceConfiguration implements DeviceProperties {
517 cfgService.getConfig(appId, SegmentRoutingAppConfig.class); 518 cfgService.getConfig(appId, SegmentRoutingAppConfig.class);
518 return (appConfig != null) ? appConfig.suppressHost() : ImmutableSet.of(); 519 return (appConfig != null) ? appConfig.suppressHost() : ImmutableSet.of();
519 } 520 }
521 +
522 + /**
523 + * Add subnet to specific connect point.
524 + *
525 + * @param cp connect point
526 + * @param ip4Prefix subnet being added to the device
527 + */
528 + public void addSubnet(ConnectPoint cp, Ip4Prefix ip4Prefix) {
529 + checkNotNull(cp);
530 + checkNotNull(ip4Prefix);
531 + SegmentRouterInfo srinfo = deviceConfigMap.get(cp.deviceId());
532 + if (srinfo == null) {
533 + log.warn("Device {} is not configured. Abort.", cp.deviceId());
534 + return;
535 + }
536 + srinfo.subnets.put(cp.port(), ip4Prefix);
537 + }
538 +
539 + /**
540 + * Remove subnet from specific connect point.
541 + *
542 + * @param cp connect point
543 + * @param ip4Prefix subnet being removed to the device
544 + */
545 + public void removeSubnet(ConnectPoint cp, Ip4Prefix ip4Prefix) {
546 + checkNotNull(cp);
547 + checkNotNull(ip4Prefix);
548 + SegmentRouterInfo srinfo = deviceConfigMap.get(cp.deviceId());
549 + if (srinfo == null) {
550 + log.warn("Device {} is not configured. Abort.", cp.deviceId());
551 + return;
552 + }
553 + srinfo.subnets.remove(cp.port(), ip4Prefix);
554 + }
520 } 555 }
......
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
18 span.s1 {font-kerning: none} 18 span.s1 {font-kerning: none}
19 span.s2 {font-kerning: none; color: #0433ff; -webkit-text-stroke: 0px #0433ff} 19 span.s2 {font-kerning: none; color: #0433ff; -webkit-text-stroke: 0px #0433ff}
20 span.s3 {font-kerning: none; color: #000000; -webkit-text-stroke: 0px #000000} 20 span.s3 {font-kerning: none; color: #000000; -webkit-text-stroke: 0px #000000}
21 - span.s4 {font-kerning: none; color: #ff40ff; -webkit-text-stroke: 0px #ff40ff} 21 + span.s4 {font-kerning: none; color: #ff9300; -webkit-text-stroke: 0px #ff9300}
22 - span.s5 {font-kerning: none; color: #ff9300; -webkit-text-stroke: 0px #ff9300} 22 + span.s5 {font-kerning: none; color: #77bb41; -webkit-text-stroke: 0px #77bb41}
23 - span.s6 {font-kerning: none; color: #77bb41; -webkit-text-stroke: 0px #77bb41} 23 + span.s6 {font-kerning: none; color: #00c7fc; -webkit-text-stroke: 0px #00c7fc}
24 - span.s7 {font-kerning: none; color: #00c7fc; -webkit-text-stroke: 0px #00c7fc} 24 + span.s7 {font-kerning: none; color: #ff40ff; -webkit-text-stroke: 0px #ff40ff}
25 span.s8 {font-kerning: none; color: #ff2600; -webkit-text-stroke: 0px #ff2600} 25 span.s8 {font-kerning: none; color: #ff2600; -webkit-text-stroke: 0px #ff2600}
26 span.s9 {font-kerning: none; color: #000000} 26 span.s9 {font-kerning: none; color: #000000}
27 span.s10 {font-kerning: none; color: #669c35; -webkit-text-stroke: 0px #669c35} 27 span.s10 {font-kerning: none; color: #669c35; -webkit-text-stroke: 0px #669c35}
...@@ -49,12 +49,6 @@ ...@@ -49,12 +49,6 @@
49 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>},</span></p> 49 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>},</span></p>
50 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p> 50 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p>
51 <p class="p2"><span class="s3"><span class="Apple-converted-space">                </span>"vlan" : "222" </span><span class="s1">// cross-connect s-tag 222 to PMC OLT</span></p> 51 <p class="p2"><span class="s3"><span class="Apple-converted-space">                </span>"vlan" : "222" </span><span class="s1">// cross-connect s-tag 222 to PMC OLT</span></p>
52 -<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>},</span></p>
53 -<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p>
54 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips" : [ "A.A.A.A/32" ] </span><span class="s4">// vSG1 public IP address /32</span></p>
55 -<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>},</span></p>
56 -<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p>
57 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips" : [ "B.B.B.B/32" ] </span><span class="s4">// vSG2 public IP address /32</span></p>
58 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 52 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
59 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p> 53 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p>
60 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p> 54 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p>
...@@ -65,25 +59,18 @@ ...@@ -65,25 +59,18 @@
65 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 59 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
66 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p> 60 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p>
67 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p> 61 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p>
68 -<p class="p3"><span class="s3"><span class="Apple-converted-space">    </span>"of:0000000000000001/30" : { </span><span class="s1">// connect to vSG3 directly without OLT (temporary)</span></p> 62 +<p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>"of:0000000000000001/65" : { </span><span class="s4">// connect to Fujitsu OLT</span></p>
69 -<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"interfaces" : [</span></p>
70 -<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p>
71 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips" : [ "C.C.C.C/32" ] </span><span class="s4">// vSG3 /32 public IP address</span></p>
72 -<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
73 -<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p>
74 -<p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p>
75 -<p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>"of:0000000000000001/65" : { </span><span class="s5">// connect to Fujitsu OLT</span></p>
76 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"interfaces" : [</span></p> 63 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"interfaces" : [</span></p>
77 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p> 64 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p>
78 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"name" : "fujitsu-olt", </span><span class="s5">// unused</span></p> 65 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"name" : "fujitsu-olt", </span><span class="s4">// unused</span></p>
79 <p class="p2"><span class="s3"><span class="Apple-converted-space">                </span>"vlan" : "69" </span><span class="s1">// cross-connect s-tag 69<span class="Apple-converted-space">  </span>to vSG</span></p> 66 <p class="p2"><span class="s3"><span class="Apple-converted-space">                </span>"vlan" : "69" </span><span class="s1">// cross-connect s-tag 69<span class="Apple-converted-space">  </span>to vSG</span></p>
80 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 67 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
81 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p> 68 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p>
82 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p> 69 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p>
83 -<p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>"of:0000000000000001/73" : { </span><span class="s5">// connect to PMC OLT</span></p> 70 +<p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>"of:0000000000000001/73" : { </span><span class="s4">// connect to PMC OLT</span></p>
84 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"interfaces" : [</span></p> 71 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"interfaces" : [</span></p>
85 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p> 72 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p>
86 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"name" : "pmc-olt", </span><span class="s5">// unused</span></p> 73 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"name" : "pmc-olt", </span><span class="s4">// unused</span></p>
87 <p class="p2"><span class="s3"><span class="Apple-converted-space">                </span>"vlan" : "222" </span><span class="s1">// cross-connect s-tag 222 to vSG</span></p> 74 <p class="p2"><span class="s3"><span class="Apple-converted-space">                </span>"vlan" : "222" </span><span class="s1">// cross-connect s-tag 222 to vSG</span></p>
88 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 75 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
89 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p> 76 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p>
...@@ -95,16 +82,16 @@ ...@@ -95,16 +82,16 @@
95 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 82 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
96 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p> 83 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>]</span></p>
97 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p> 84 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>},</span></p>
98 -<p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>"of:0000000000000002/32" : { </span><span class="s6">// connect to Internet router</span></p> 85 +<p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>"of:0000000000000002/32" : { </span><span class="s5">// connect to Internet router</span></p>
99 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"interfaces" : [</span></p> 86 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"interfaces" : [</span></p>
100 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p> 87 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>{</span></p>
101 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"name" : "external-quagga", </span><span class="s6">// Internet router interface name</span></p> 88 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"name" : "external-quagga", </span><span class="s5">// Internet router interface name</span></p>
102 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips" : [ "10.231.254.202/30", "10.231.254.223/32" ], </span><span class="s6">// Quagga IP addresses</span></p> 89 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips" : [ "10.231.254.202/30", "10.231.254.223/32" ], </span><span class="s5">// Quagga IP addresses</span></p>
103 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"mac" : "00:16:3e:56:2b:48" </span><span class="s6">// Quagga WAN MAC</span></p> 90 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"mac" : "00:16:3e:56:2b:48" </span><span class="s5">// Quagga WAN MAC</span></p>
104 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 91 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
105 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>],</span></p> 92 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>],</span></p>
106 -<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"pimInterface" : { </span><span class="s7">// PIM configuration</span></p> 93 +<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"pimInterface" : { </span><span class="s6">// PIM configuration</span></p>
107 -<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"interfaceName" : "external-quagga", </span><span class="s7">// port that faces the Internet router</span></p> 94 +<p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"interfaceName" : "external-quagga", </span><span class="s6">// port that faces the Internet router</span></p>
108 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"enabled" : true,</span></p> 95 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"enabled" : true,</span></p>
109 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"helloInterval" : 1,</span></p> 96 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"helloInterval" : 1,</span></p>
110 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"holdTime" : 3,</span></p> 97 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"holdTime" : 3,</span></p>
...@@ -162,15 +149,15 @@ ...@@ -162,15 +149,15 @@
162 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/5" </span><span class="s2">// node 1 location</span></p> 149 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/5" </span><span class="s2">// node 1 location</span></p>
163 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 150 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
164 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p> 151 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p>
165 -<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"02:42:cf:8d:c0:82/-1" : { </span><span class="s4">// vSG1</span></p> 152 +<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"02:42:cf:8d:c0:82/-1" : { </span><span class="s7">// vSG1</span></p>
166 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"basic": {</span></p> 153 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"basic": {</span></p>
167 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips": ["A.A.A.A"], </span><span class="s4">// vSG1 public IP address</span></p> 154 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips": ["A.A.A.A"], </span><span class="s7">// vSG1 public IP address</span></p>
168 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/5"</span></p> 155 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/5"</span></p>
169 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 156 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
170 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p> 157 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p>
171 -<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"02:42:cf:8d:c0:83/-1" : { </span><span class="s4">// vSG2</span></p> 158 +<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"02:42:cf:8d:c0:83/-1" : { </span><span class="s7">// vSG2</span></p>
172 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"basic": {</span></p> 159 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"basic": {</span></p>
173 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips": ["B.B.B.B"], </span><span class="s4">// vSG2 public IP address</span></p> 160 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips": ["B.B.B.B"], </span><span class="s7">// vSG2 public IP address</span></p>
174 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/5"</span></p> 161 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/5"</span></p>
175 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 162 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
176 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p> 163 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p>
...@@ -180,9 +167,9 @@ ...@@ -180,9 +167,9 @@
180 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/7"</span></p> 167 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/7"</span></p>
181 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 168 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
182 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p> 169 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p>
183 -<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"74:44:01:74:61:92/-1" : { </span><span class="s4">// vSG3</span></p> 170 +<p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"74:44:01:74:61:92/-1" : { </span><span class="s7">// vSG3</span></p>
184 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"basic": {</span></p> 171 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"basic": {</span></p>
185 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips": ["C.C.C.C"], </span><span class="s4">// vSG3 public IP address</span></p> 172 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ips": ["C.C.C.C"], </span><span class="s7">// vSG3 public IP address</span></p>
186 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/30"</span></p> 173 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"location": "of:0000000000000001/30"</span></p>
187 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 174 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
188 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p> 175 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p>
...@@ -234,7 +221,7 @@ ...@@ -234,7 +221,7 @@
234 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"vRouterMacs" : [</span></p> 221 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"vRouterMacs" : [</span></p>
235 <p class="p3"><span class="s3"><span class="Apple-converted-space">                    </span>"a4:23:05:34:56:78" </span><span class="s1">// vRouter LAN MAC (vSG’s default gateway)</span></p> 222 <p class="p3"><span class="s3"><span class="Apple-converted-space">                    </span>"a4:23:05:34:56:78" </span><span class="s1">// vRouter LAN MAC (vSG’s default gateway)</span></p>
236 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>],</span></p> 223 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>],</span></p>
237 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"vRouterId" : "of:0000000000000002", </span><span class="s4">// vRouter DPID (0/0 is replaced by this)</span></p> 224 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"vRouterId" : "of:0000000000000002", </span><span class="s7">// vRouter DPID (0/0 is replaced by this)</span></p>
238 <p class="p4"><span class="s3"><span class="Apple-converted-space">                 </span>"suppressSubnet" : [ </span><span class="s1">// Do not push subnet rules for these ports</span></p> 225 <p class="p4"><span class="s3"><span class="Apple-converted-space">                 </span>"suppressSubnet" : [ </span><span class="s1">// Do not push subnet rules for these ports</span></p>
239 <p class="p7"><span class="s1"><span class="Apple-converted-space">                    </span>"of:0000000000000002/31", "of:0000000000000002/32"</span></p> 226 <p class="p7"><span class="s1"><span class="Apple-converted-space">                    </span>"of:0000000000000002/31", "of:0000000000000002/32"</span></p>
240 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>],</span></p> 227 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>],</span></p>
...@@ -246,10 +233,10 @@ ...@@ -246,10 +233,10 @@
246 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p> 233 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>},</span></p>
247 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"org.onosproject.router" : {</span></p> 234 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>"org.onosproject.router" : {</span></p>
248 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"router" : {</span></p> 235 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>"router" : {</span></p>
249 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"controlPlaneConnectPoint" : "of:0000000000000002/31", </span><span class="s6">// location of Quagga</span></p> 236 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"controlPlaneConnectPoint" : "of:0000000000000002/31", </span><span class="s5">// location of Quagga</span></p>
250 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ospfEnabled" : "true", </span><span class="s6">// enable OSPF</span></p> 237 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ospfEnabled" : "true", </span><span class="s5">// enable OSPF</span></p>
251 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"pimEnabled" : "true", </span><span class="s7">// enable PIM</span></p> 238 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"pimEnabled" : "true", </span><span class="s6">// enable PIM</span></p>
252 -<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"interfaces" : [ "external-quagga" ] </span><span class="s10">// </span><span class="s6">VR only handles peers on these ports</span></p> 239 +<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"interfaces" : [ "external-quagga" ] </span><span class="s10">// </span><span class="s5">VR only handles peers on these ports</span></p>
253 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p> 240 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
254 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>}</span></p> 241 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>}</span></p>
255 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>}</span></p> 242 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>}</span></p>
......
...@@ -13,12 +13,6 @@ ...@@ -13,12 +13,6 @@
13 }, 13 },
14 { 14 {
15 "vlan" : "222" 15 "vlan" : "222"
16 - },
17 - {
18 - "ips" : [
19 - "A.A.A.146/32", "A.A.A.147/32", "A.A.A.148/32", "A.A.A.149/32",
20 - "A.A.A.150/32", "A.A.A.151/32", "A.A.A.152/32", "A.A.A.153/32"
21 - ]
22 } 16 }
23 ] 17 ]
24 }, 18 },
...@@ -52,9 +46,6 @@ ...@@ -52,9 +46,6 @@
52 "interfaces" : [ 46 "interfaces" : [
53 { 47 {
54 "ips" : [ "10.0.2.254/24" ] 48 "ips" : [ "10.0.2.254/24" ]
55 - },
56 - {
57 - "ips" : [ "A.A.A.130/32", "A.A.A.131/32" ]
58 } 49 }
59 ] 50 ]
60 }, 51 },
......