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
162 additions
and
35 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 | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -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 | } | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -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