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