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
Showing
7 changed files
with
340 additions
and
179 deletions
| ... | @@ -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 | }, | ... | ... |
-
Please register or login to post a comment