Committed by
Gerrit Code Review
ONOS-685: Network Configuration Manager support for Segment Routing application
Change-Id: Ia15bfd24559dd5542633c8b76d500b2d31362340
Showing
25 changed files
with
2077 additions
and
486 deletions
apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandlerApp.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015 Open Networking Laboratory | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.onosproject.grouphandler; | ||
17 | - | ||
18 | -import static org.slf4j.LoggerFactory.getLogger; | ||
19 | - | ||
20 | -import java.net.URI; | ||
21 | -import java.util.Arrays; | ||
22 | -import java.util.HashMap; | ||
23 | -import java.util.HashSet; | ||
24 | -import java.util.List; | ||
25 | - | ||
26 | -import org.apache.felix.scr.annotations.Activate; | ||
27 | -import org.apache.felix.scr.annotations.Component; | ||
28 | -import org.apache.felix.scr.annotations.Deactivate; | ||
29 | -import org.apache.felix.scr.annotations.Reference; | ||
30 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
31 | -import org.onlab.packet.MacAddress; | ||
32 | -import org.onlab.util.KryoNamespace; | ||
33 | -import org.onosproject.core.ApplicationId; | ||
34 | -import org.onosproject.core.CoreService; | ||
35 | -import org.onosproject.mastership.MastershipService; | ||
36 | -import org.onosproject.net.Device; | ||
37 | -import org.onosproject.net.DeviceId; | ||
38 | -import org.onosproject.net.MastershipRole; | ||
39 | -import org.onosproject.net.device.DeviceEvent; | ||
40 | -import org.onosproject.net.device.DeviceListener; | ||
41 | -import org.onosproject.net.device.DeviceService; | ||
42 | -import org.onosproject.net.group.GroupService; | ||
43 | -import org.onosproject.net.link.LinkEvent; | ||
44 | -import org.onosproject.net.link.LinkListener; | ||
45 | -import org.onosproject.net.link.LinkService; | ||
46 | -import org.onosproject.net.topology.TopologyService; | ||
47 | -import org.slf4j.Logger; | ||
48 | - | ||
49 | -/** | ||
50 | - * Sample application to verify group subsystem end to end. | ||
51 | - * This application expects a network of maximum of six connected | ||
52 | - * devices for the test to work. For every device in the network, | ||
53 | - * this test application launches a default group handler function | ||
54 | - * that creates ECMP groups for every neighbor the device is | ||
55 | - * connected to. | ||
56 | - */ | ||
57 | -@Component(immediate = true) | ||
58 | -public class DefaultGroupHandlerApp { | ||
59 | - | ||
60 | - private final Logger log = getLogger(getClass()); | ||
61 | - | ||
62 | - private final DeviceProperties config = new DeviceConfiguration(); | ||
63 | - private ApplicationId appId; | ||
64 | - private HashMap<DeviceId, DefaultGroupHandler> dghMap = | ||
65 | - new HashMap<DeviceId, DefaultGroupHandler>(); | ||
66 | - | ||
67 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
68 | - protected TopologyService topologyService; | ||
69 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
70 | - protected DeviceService deviceService; | ||
71 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
72 | - protected LinkService linkService; | ||
73 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
74 | - protected GroupService groupService; | ||
75 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
76 | - protected CoreService coreService; | ||
77 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
78 | - protected MastershipService mastershipService; | ||
79 | - | ||
80 | - private DeviceListener deviceListener = new InternalDeviceListener(); | ||
81 | - private LinkListener linkListener = new InternalLinkListener(); | ||
82 | - | ||
83 | - protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() | ||
84 | - .register(URI.class) | ||
85 | - .register(HashSet.class) | ||
86 | - .register(DeviceId.class) | ||
87 | - .register(NeighborSet.class); | ||
88 | - | ||
89 | - @Activate | ||
90 | - public void activate() { | ||
91 | - appId = coreService.registerApplication("org.onosproject.defaultgrouphandler"); | ||
92 | - log.info("DefaultGroupHandlerApp Activating"); | ||
93 | - | ||
94 | - deviceService.addListener(deviceListener); | ||
95 | - linkService.addListener(linkListener); | ||
96 | - for (Device device: deviceService.getDevices()) { | ||
97 | - if (mastershipService. | ||
98 | - getLocalRole(device.id()) == MastershipRole.MASTER) { | ||
99 | - log.debug("Initiating default group handling for {}", device.id()); | ||
100 | - DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device.id(), | ||
101 | - appId, | ||
102 | - config, | ||
103 | - linkService, | ||
104 | - groupService); | ||
105 | - dgh.createGroups(); | ||
106 | - dghMap.put(device.id(), dgh); | ||
107 | - } else { | ||
108 | - log.debug("Activate: Local role {} " | ||
109 | - + "is not MASTER for device {}", | ||
110 | - mastershipService. | ||
111 | - getLocalRole(device.id()), | ||
112 | - device.id()); | ||
113 | - } | ||
114 | - } | ||
115 | - | ||
116 | - log.info("Activated"); | ||
117 | - } | ||
118 | - | ||
119 | - @Deactivate | ||
120 | - public void deactivate() { | ||
121 | - dghMap.clear(); | ||
122 | - } | ||
123 | - | ||
124 | - public class DeviceConfiguration implements DeviceProperties { | ||
125 | - private final List<Integer> allSegmentIds = | ||
126 | - Arrays.asList(101, 102, 103, 104, 105, 106); | ||
127 | - private HashMap<DeviceId, Integer> deviceSegmentIdMap = | ||
128 | - new HashMap<DeviceId, Integer>() { | ||
129 | - { | ||
130 | - put(DeviceId.deviceId("of:0000000000000001"), 101); | ||
131 | - put(DeviceId.deviceId("of:0000000000000002"), 102); | ||
132 | - put(DeviceId.deviceId("of:0000000000000003"), 103); | ||
133 | - put(DeviceId.deviceId("of:0000000000000004"), 104); | ||
134 | - put(DeviceId.deviceId("of:0000000000000005"), 105); | ||
135 | - put(DeviceId.deviceId("of:0000000000000006"), 106); | ||
136 | - } | ||
137 | - }; | ||
138 | - private final HashMap<DeviceId, MacAddress> deviceMacMap = | ||
139 | - new HashMap<DeviceId, MacAddress>() { | ||
140 | - { | ||
141 | - put(DeviceId.deviceId("of:0000000000000001"), | ||
142 | - MacAddress.valueOf("00:00:00:00:00:01")); | ||
143 | - put(DeviceId.deviceId("of:0000000000000002"), | ||
144 | - MacAddress.valueOf("00:00:00:00:00:02")); | ||
145 | - put(DeviceId.deviceId("of:0000000000000003"), | ||
146 | - MacAddress.valueOf("00:00:00:00:00:03")); | ||
147 | - put(DeviceId.deviceId("of:0000000000000004"), | ||
148 | - MacAddress.valueOf("00:00:00:00:00:04")); | ||
149 | - put(DeviceId.deviceId("of:0000000000000005"), | ||
150 | - MacAddress.valueOf("00:00:00:00:00:05")); | ||
151 | - put(DeviceId.deviceId("of:0000000000000006"), | ||
152 | - MacAddress.valueOf("00:00:00:00:00:06")); | ||
153 | - } | ||
154 | - }; | ||
155 | - | ||
156 | - @Override | ||
157 | - public int getSegmentId(DeviceId deviceId) { | ||
158 | - if (deviceSegmentIdMap.get(deviceId) != null) { | ||
159 | - log.debug("getSegmentId for device{} is {}", | ||
160 | - deviceId, | ||
161 | - deviceSegmentIdMap.get(deviceId)); | ||
162 | - return deviceSegmentIdMap.get(deviceId); | ||
163 | - } else { | ||
164 | - throw new IllegalStateException(); | ||
165 | - } | ||
166 | - } | ||
167 | - @Override | ||
168 | - public MacAddress getDeviceMac(DeviceId deviceId) { | ||
169 | - if (deviceMacMap.get(deviceId) != null) { | ||
170 | - log.debug("getDeviceMac for device{} is {}", | ||
171 | - deviceId, | ||
172 | - deviceMacMap.get(deviceId)); | ||
173 | - return deviceMacMap.get(deviceId); | ||
174 | - } else { | ||
175 | - throw new IllegalStateException(); | ||
176 | - } | ||
177 | - } | ||
178 | - @Override | ||
179 | - public boolean isEdgeDevice(DeviceId deviceId) { | ||
180 | - return true; | ||
181 | - } | ||
182 | - @Override | ||
183 | - public List<Integer> getAllDeviceSegmentIds() { | ||
184 | - return allSegmentIds; | ||
185 | - } | ||
186 | - } | ||
187 | - | ||
188 | - private class InternalDeviceListener implements DeviceListener { | ||
189 | - | ||
190 | - @Override | ||
191 | - public void event(DeviceEvent event) { | ||
192 | - if (mastershipService. | ||
193 | - getLocalRole(event.subject().id()) != MastershipRole.MASTER) { | ||
194 | - log.debug("Local role {} is not MASTER for device {}", | ||
195 | - mastershipService. | ||
196 | - getLocalRole(event.subject().id()), | ||
197 | - event.subject().id()); | ||
198 | - return; | ||
199 | - } | ||
200 | - switch (event.type()) { | ||
201 | - case DEVICE_ADDED: | ||
202 | - log.debug("Initiating default group handling for {}", event.subject().id()); | ||
203 | - DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler( | ||
204 | - event.subject().id(), | ||
205 | - appId, | ||
206 | - config, | ||
207 | - linkService, | ||
208 | - groupService); | ||
209 | - dgh.createGroups(); | ||
210 | - dghMap.put(event.subject().id(), dgh); | ||
211 | - break; | ||
212 | - case PORT_REMOVED: | ||
213 | - if (dghMap.get(event.subject().id()) != null) { | ||
214 | - dghMap.get(event.subject().id()).portDown(event.port().number()); | ||
215 | - } | ||
216 | - break; | ||
217 | - default: | ||
218 | - break; | ||
219 | - } | ||
220 | - | ||
221 | - } | ||
222 | - } | ||
223 | - | ||
224 | - private class InternalLinkListener implements LinkListener { | ||
225 | - | ||
226 | - @Override | ||
227 | - public void event(LinkEvent event) { | ||
228 | - if (mastershipService. | ||
229 | - getLocalRole(event.subject().src().deviceId()) != | ||
230 | - MastershipRole.MASTER) { | ||
231 | - log.debug("InternalLinkListener: Local role {} " | ||
232 | - + "is not MASTER for device {}", | ||
233 | - mastershipService. | ||
234 | - getLocalRole(event.subject().src().deviceId()), | ||
235 | - event.subject().src().deviceId()); | ||
236 | - return; | ||
237 | - } | ||
238 | - switch (event.type()) { | ||
239 | - case LINK_ADDED: | ||
240 | - if (dghMap.get(event.subject().src().deviceId()) != null) { | ||
241 | - dghMap.get(event.subject().src().deviceId()).linkUp(event.subject()); | ||
242 | - } | ||
243 | - break; | ||
244 | - default: | ||
245 | - break; | ||
246 | - } | ||
247 | - } | ||
248 | - | ||
249 | - } | ||
250 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -45,7 +45,6 @@ | ... | @@ -45,7 +45,6 @@ |
45 | <module>reactive-routing</module> | 45 | <module>reactive-routing</module> |
46 | <module>bgprouter</module> | 46 | <module>bgprouter</module> |
47 | <module>test</module> | 47 | <module>test</module> |
48 | - <module>grouphandler</module> | ||
49 | <module>segmentrouting</module> | 48 | <module>segmentrouting</module> |
50 | </modules> | 49 | </modules> |
51 | 50 | ... | ... |
... | @@ -19,7 +19,6 @@ import org.onlab.packet.ARP; | ... | @@ -19,7 +19,6 @@ import org.onlab.packet.ARP; |
19 | import org.onlab.packet.Ethernet; | 19 | import org.onlab.packet.Ethernet; |
20 | import org.onlab.packet.Ip4Address; | 20 | import org.onlab.packet.Ip4Address; |
21 | import org.onlab.packet.IpAddress; | 21 | import org.onlab.packet.IpAddress; |
22 | -import org.onlab.packet.IpPrefix; | ||
23 | import org.onlab.packet.MacAddress; | 22 | import org.onlab.packet.MacAddress; |
24 | import org.onosproject.net.ConnectPoint; | 23 | import org.onosproject.net.ConnectPoint; |
25 | import org.onosproject.net.DeviceId; | 24 | import org.onosproject.net.DeviceId; |
... | @@ -36,7 +35,7 @@ import org.slf4j.Logger; | ... | @@ -36,7 +35,7 @@ import org.slf4j.Logger; |
36 | import org.slf4j.LoggerFactory; | 35 | import org.slf4j.LoggerFactory; |
37 | 36 | ||
38 | import java.nio.ByteBuffer; | 37 | import java.nio.ByteBuffer; |
39 | - | 38 | +import java.util.List; |
40 | import static com.google.common.base.Preconditions.checkNotNull; | 39 | import static com.google.common.base.Preconditions.checkNotNull; |
41 | 40 | ||
42 | public class ArpHandler { | 41 | public class ArpHandler { |
... | @@ -112,11 +111,11 @@ public class ArpHandler { | ... | @@ -112,11 +111,11 @@ public class ArpHandler { |
112 | 111 | ||
113 | 112 | ||
114 | private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) { | 113 | private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) { |
115 | - Ip4Address gatewayIpAddress = config.getGatewayIpAddress(deviceId); | 114 | + List<Ip4Address> gatewayIpAddresses = config.getGatewayIpAddress(deviceId); |
116 | - if (gatewayIpAddress != null) { | 115 | + if (gatewayIpAddresses != null) { |
117 | Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest | 116 | Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest |
118 | .getTargetProtocolAddress()); | 117 | .getTargetProtocolAddress()); |
119 | - if (gatewayIpAddress.equals(targetProtocolAddress)) { | 118 | + if (gatewayIpAddresses.contains(targetProtocolAddress)) { |
120 | return true; | 119 | return true; |
121 | } | 120 | } |
122 | } | 121 | } |
... | @@ -124,15 +123,11 @@ public class ArpHandler { | ... | @@ -124,15 +123,11 @@ public class ArpHandler { |
124 | } | 123 | } |
125 | 124 | ||
126 | private boolean isArpReqForSubnet(DeviceId deviceId, ARP arpRequest) { | 125 | private boolean isArpReqForSubnet(DeviceId deviceId, ARP arpRequest) { |
127 | - String subnetInfo = config.getSubnetInfo(deviceId); | 126 | + return config.getSubnetInfo(deviceId).stream() |
128 | - if (subnetInfo != null) { | 127 | + .anyMatch((prefix)-> |
129 | - IpPrefix prefix = IpPrefix.valueOf(subnetInfo); | 128 | + prefix.contains(Ip4Address. |
130 | - if (prefix.contains(Ip4Address.valueOf(arpRequest.getTargetProtocolAddress()))) { | 129 | + valueOf(arpRequest. |
131 | - return true; | 130 | + getTargetProtocolAddress()))); |
132 | - } | ||
133 | - } | ||
134 | - | ||
135 | - return false; | ||
136 | } | 131 | } |
137 | 132 | ||
138 | /** | 133 | /** | ... | ... |
... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.segmentrouting; | 16 | package org.onosproject.segmentrouting; |
17 | 17 | ||
18 | +import org.onlab.packet.Ip4Prefix; | ||
18 | import org.onlab.packet.IpPrefix; | 19 | import org.onlab.packet.IpPrefix; |
19 | import org.onosproject.net.Device; | 20 | import org.onosproject.net.Device; |
20 | import org.onosproject.net.DeviceId; | 21 | import org.onosproject.net.DeviceId; |
... | @@ -26,6 +27,7 @@ import org.slf4j.LoggerFactory; | ... | @@ -26,6 +27,7 @@ import org.slf4j.LoggerFactory; |
26 | import java.util.ArrayList; | 27 | import java.util.ArrayList; |
27 | import java.util.HashMap; | 28 | import java.util.HashMap; |
28 | import java.util.HashSet; | 29 | import java.util.HashSet; |
30 | +import java.util.List; | ||
29 | import java.util.Set; | 31 | import java.util.Set; |
30 | 32 | ||
31 | import static com.google.common.base.Preconditions.checkNotNull; | 33 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -139,8 +141,11 @@ public class DefaultRoutingHandler { | ... | @@ -139,8 +141,11 @@ public class DefaultRoutingHandler { |
139 | // If both target switch and dest switch are edge routers, then set IP rule | 141 | // If both target switch and dest switch are edge routers, then set IP rule |
140 | // for both subnet and router IP. | 142 | // for both subnet and router IP. |
141 | if (config.isEdgeRouter(targetSw) && config.isEdgeRouter(destSw)) { | 143 | if (config.isEdgeRouter(targetSw) && config.isEdgeRouter(destSw)) { |
142 | - String subnets = config.getSubnetInfo(destSw); | 144 | + List<Ip4Prefix> subnets = config.getSubnetInfo(destSw); |
143 | - result = rulePopulator.populateIpRuleForSubnet(targetSw, subnets, destSw, nextHops); | 145 | + result = rulePopulator.populateIpRuleForSubnet(targetSw, |
146 | + subnets, | ||
147 | + destSw, | ||
148 | + nextHops); | ||
144 | if (!result) { | 149 | if (!result) { |
145 | return false; | 150 | return false; |
146 | } | 151 | } | ... | ... |
1 | package org.onosproject.segmentrouting; | 1 | package org.onosproject.segmentrouting; |
2 | 2 | ||
3 | import org.onlab.packet.Ip4Address; | 3 | import org.onlab.packet.Ip4Address; |
4 | +import org.onlab.packet.Ip4Prefix; | ||
5 | +import org.onlab.packet.IpPrefix; | ||
4 | import org.onlab.packet.MacAddress; | 6 | import org.onlab.packet.MacAddress; |
5 | -import org.onosproject.grouphandler.DeviceProperties; | 7 | +import org.onosproject.segmentrouting.grouphandler.DeviceProperties; |
6 | import org.onosproject.net.DeviceId; | 8 | import org.onosproject.net.DeviceId; |
9 | +import org.onosproject.net.PortNumber; | ||
10 | +import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig; | ||
11 | +import org.onosproject.segmentrouting.config.NetworkConfigManager; | ||
12 | +import org.onosproject.segmentrouting.config.SegmentRouterConfig; | ||
13 | +import org.onosproject.segmentrouting.config.SegmentRouterConfig.Subnet; | ||
7 | import org.slf4j.Logger; | 14 | import org.slf4j.Logger; |
8 | import org.slf4j.LoggerFactory; | 15 | import org.slf4j.LoggerFactory; |
9 | 16 | ||
10 | -import java.util.Arrays; | 17 | +import static com.google.common.base.Preconditions.checkNotNull; |
18 | + | ||
19 | +import java.util.ArrayList; | ||
11 | import java.util.HashMap; | 20 | import java.util.HashMap; |
12 | import java.util.List; | 21 | import java.util.List; |
13 | import java.util.Map; | 22 | import java.util.Map; |
14 | 23 | ||
24 | +/** | ||
25 | + * Segment Routing configuration component that reads the | ||
26 | + * segment routing related configuration from Network Configuration Manager | ||
27 | + * component and organizes in more accessible formats. | ||
28 | + * | ||
29 | + * TODO: Merge multiple Segment Routing configuration wrapper classes into one. | ||
30 | + */ | ||
15 | public class DeviceConfiguration implements DeviceProperties { | 31 | public class DeviceConfiguration implements DeviceProperties { |
16 | 32 | ||
17 | private static final Logger log = LoggerFactory | 33 | private static final Logger log = LoggerFactory |
18 | .getLogger(DeviceConfiguration.class); | 34 | .getLogger(DeviceConfiguration.class); |
19 | - private final List<Integer> allSegmentIds = | 35 | + private final List<Integer> allSegmentIds = new ArrayList<Integer>(); |
20 | - Arrays.asList(101, 102, 103, 104, 105, 106); | 36 | + private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>(); |
21 | - private HashMap<DeviceId, Integer> deviceSegmentIdMap = | 37 | + private final NetworkConfigManager configService; |
22 | - new HashMap<DeviceId, Integer>() { | 38 | + |
23 | - { | 39 | + private class SegmentRouterInfo { |
24 | - put(DeviceId.deviceId("of:0000000000000001"), 101); | 40 | + int nodeSid; |
25 | - put(DeviceId.deviceId("of:0000000000000002"), 102); | 41 | + DeviceId deviceId; |
26 | - put(DeviceId.deviceId("of:0000000000000003"), 103); | 42 | + Ip4Address ip; |
27 | - put(DeviceId.deviceId("of:0000000000000004"), 104); | 43 | + MacAddress mac; |
28 | - put(DeviceId.deviceId("of:0000000000000005"), 105); | 44 | + boolean isEdge; |
29 | - put(DeviceId.deviceId("of:0000000000000006"), 106); | 45 | + HashMap<PortNumber, Ip4Address> gatewayIps; |
30 | - } | 46 | + HashMap<PortNumber, Ip4Prefix> subnets; |
31 | - }; | 47 | + } |
32 | - private final HashMap<DeviceId, MacAddress> deviceMacMap = | 48 | + |
33 | - new HashMap<DeviceId, MacAddress>() { | 49 | + /** |
34 | - { | 50 | + * Constructor. Reads all the configuration for all devices of type |
35 | - put(DeviceId.deviceId("of:0000000000000001"), | 51 | + * Segment Router and organizes into various maps for easier access. |
36 | - MacAddress.valueOf("00:00:00:00:00:01")); | 52 | + * |
37 | - put(DeviceId.deviceId("of:0000000000000002"), | 53 | + * @param configService handle to network configuration manager |
38 | - MacAddress.valueOf("00:00:00:00:00:02")); | 54 | + * component from where the relevant configuration is retrieved. |
39 | - put(DeviceId.deviceId("of:0000000000000003"), | 55 | + */ |
40 | - MacAddress.valueOf("00:00:00:00:00:03")); | 56 | + public DeviceConfiguration(NetworkConfigManager configService) { |
41 | - put(DeviceId.deviceId("of:0000000000000004"), | 57 | + this.configService = checkNotNull(configService); |
42 | - MacAddress.valueOf("00:00:00:00:00:04")); | 58 | + List<SwitchConfig> allSwitchCfg = |
43 | - put(DeviceId.deviceId("of:0000000000000005"), | 59 | + this.configService.getConfiguredAllowedSwitches(); |
44 | - MacAddress.valueOf("00:00:00:00:00:05")); | 60 | + for (SwitchConfig cfg : allSwitchCfg) { |
45 | - put(DeviceId.deviceId("of:0000000000000006"), | 61 | + if (!(cfg instanceof SegmentRouterConfig)) { |
46 | - MacAddress.valueOf("00:00:00:00:00:06")); | 62 | + continue; |
47 | - } | 63 | + } |
48 | - }; | 64 | + SegmentRouterInfo info = new SegmentRouterInfo(); |
49 | - | 65 | + info.nodeSid = ((SegmentRouterConfig) cfg).getNodeSid(); |
50 | - private final HashMap<DeviceId, Ip4Address> deviceIpMap = | 66 | + info.deviceId = ((SegmentRouterConfig) cfg).getDpid(); |
51 | - new HashMap<DeviceId, Ip4Address>() { | 67 | + info.mac = MacAddress.valueOf((( |
52 | - { | 68 | + SegmentRouterConfig) cfg).getRouterMac()); |
53 | - put(DeviceId.deviceId("of:0000000000000001"), | 69 | + String routerIp = ((SegmentRouterConfig) cfg).getRouterIp(); |
54 | - Ip4Address.valueOf("192.168.0.1")); | 70 | + Ip4Prefix prefix = checkNotNull(IpPrefix.valueOf(routerIp).getIp4Prefix()); |
55 | - put(DeviceId.deviceId("of:0000000000000002"), | 71 | + info.ip = prefix.address(); |
56 | - Ip4Address.valueOf("192.168.0.2")); | 72 | + info.isEdge = ((SegmentRouterConfig) cfg).isEdgeRouter(); |
57 | - put(DeviceId.deviceId("of:0000000000000003"), | 73 | + info.subnets = new HashMap<>(); |
58 | - Ip4Address.valueOf("192.168.0.3")); | 74 | + info.gatewayIps = new HashMap<PortNumber, Ip4Address>(); |
59 | - put(DeviceId.deviceId("of:0000000000000004"), | 75 | + for (Subnet s: ((SegmentRouterConfig) cfg).getSubnets()) { |
60 | - Ip4Address.valueOf("192.168.0.4")); | 76 | + info.subnets.put(PortNumber.portNumber(s.getPortNo()), |
61 | - put(DeviceId.deviceId("of:0000000000000005"), | 77 | + Ip4Prefix.valueOf(s.getSubnetIp())); |
62 | - Ip4Address.valueOf("192.168.0.5")); | 78 | + String gatewayIp = s.getSubnetIp(). |
63 | - put(DeviceId.deviceId("of:0000000000000006"), | 79 | + substring(0, s.getSubnetIp().indexOf('/')); |
64 | - Ip4Address.valueOf("192.168.0.6")); | 80 | + info.gatewayIps.put(PortNumber.portNumber(s.getPortNo()), |
65 | - } | 81 | + Ip4Address.valueOf(gatewayIp)); |
66 | - }; | 82 | + } |
83 | + this.deviceConfigMap.put(info.deviceId, info); | ||
84 | + this.allSegmentIds.add(info.nodeSid); | ||
85 | + } | ||
86 | + } | ||
67 | 87 | ||
88 | + /** | ||
89 | + * Returns the segment id of a segment router. | ||
90 | + * | ||
91 | + * @param deviceId device identifier | ||
92 | + * @return segment id | ||
93 | + */ | ||
68 | @Override | 94 | @Override |
69 | public int getSegmentId(DeviceId deviceId) { | 95 | public int getSegmentId(DeviceId deviceId) { |
70 | - if (deviceSegmentIdMap.get(deviceId) != null) { | 96 | + if (deviceConfigMap.get(deviceId) != null) { |
71 | log.debug("getSegmentId for device{} is {}", | 97 | log.debug("getSegmentId for device{} is {}", |
72 | deviceId, | 98 | deviceId, |
73 | - deviceSegmentIdMap.get(deviceId)); | 99 | + deviceConfigMap.get(deviceId).nodeSid); |
74 | - return deviceSegmentIdMap.get(deviceId); | 100 | + return deviceConfigMap.get(deviceId).nodeSid; |
75 | } else { | 101 | } else { |
76 | throw new IllegalStateException(); | 102 | throw new IllegalStateException(); |
77 | } | 103 | } |
78 | } | 104 | } |
79 | 105 | ||
106 | + /** | ||
107 | + * Returns the segment id of a segment router given its mac address. | ||
108 | + * | ||
109 | + * @param routerMac router mac address | ||
110 | + * @return segment id | ||
111 | + */ | ||
112 | + public int getSegmentId(MacAddress routerMac) { | ||
113 | + for (Map.Entry<DeviceId, SegmentRouterInfo> entry: | ||
114 | + deviceConfigMap.entrySet()) { | ||
115 | + if (entry.getValue().mac.equals(routerMac)) { | ||
116 | + return entry.getValue().nodeSid; | ||
117 | + } | ||
118 | + } | ||
119 | + | ||
120 | + return -1; | ||
121 | + } | ||
122 | + | ||
123 | + /** | ||
124 | + * Returns the segment id of a segment router given its router ip address. | ||
125 | + * | ||
126 | + * @param routerAddress router ip address | ||
127 | + * @return segment id | ||
128 | + */ | ||
129 | + public int getSegmentId(Ip4Address routerAddress) { | ||
130 | + for (Map.Entry<DeviceId, SegmentRouterInfo> entry: | ||
131 | + deviceConfigMap.entrySet()) { | ||
132 | + if (entry.getValue().ip.equals(routerAddress)) { | ||
133 | + return entry.getValue().nodeSid; | ||
134 | + } | ||
135 | + } | ||
136 | + | ||
137 | + return -1; | ||
138 | + } | ||
80 | 139 | ||
140 | + /** | ||
141 | + * Returns the router mac of a segment router. | ||
142 | + * | ||
143 | + * @param deviceId device identifier | ||
144 | + * @return router mac address | ||
145 | + */ | ||
81 | @Override | 146 | @Override |
82 | public MacAddress getDeviceMac(DeviceId deviceId) { | 147 | public MacAddress getDeviceMac(DeviceId deviceId) { |
83 | - if (deviceMacMap.get(deviceId) != null) { | 148 | + if (deviceConfigMap.get(deviceId) != null) { |
84 | log.debug("getDeviceMac for device{} is {}", | 149 | log.debug("getDeviceMac for device{} is {}", |
85 | deviceId, | 150 | deviceId, |
86 | - deviceMacMap.get(deviceId)); | 151 | + deviceConfigMap.get(deviceId).mac); |
87 | - return deviceMacMap.get(deviceId); | 152 | + return deviceConfigMap.get(deviceId).mac; |
88 | } else { | 153 | } else { |
89 | throw new IllegalStateException(); | 154 | throw new IllegalStateException(); |
90 | } | 155 | } |
91 | } | 156 | } |
92 | 157 | ||
158 | + /** | ||
159 | + * Returns the router ip address of a segment router. | ||
160 | + * | ||
161 | + * @param deviceId device identifier | ||
162 | + * @return router ip address | ||
163 | + */ | ||
164 | + public Ip4Address getRouterIp(DeviceId deviceId) { | ||
165 | + if (deviceConfigMap.get(deviceId) != null) { | ||
166 | + log.debug("getDeviceIp for device{} is {}", | ||
167 | + deviceId, | ||
168 | + deviceConfigMap.get(deviceId).ip); | ||
169 | + return deviceConfigMap.get(deviceId).ip; | ||
170 | + } else { | ||
171 | + throw new IllegalStateException(); | ||
172 | + } | ||
173 | + } | ||
93 | 174 | ||
175 | + /** | ||
176 | + * Indicates if the segment router is a edge router or | ||
177 | + * a transit/back bone router. | ||
178 | + * | ||
179 | + * @param deviceId device identifier | ||
180 | + * @return boolean | ||
181 | + */ | ||
94 | @Override | 182 | @Override |
95 | public boolean isEdgeDevice(DeviceId deviceId) { | 183 | public boolean isEdgeDevice(DeviceId deviceId) { |
96 | - if (deviceId.equals(DeviceId.deviceId("of:0000000000000001")) | 184 | + if (deviceConfigMap.get(deviceId) != null) { |
97 | - || deviceId.equals(DeviceId.deviceId("of:0000000000000006"))) { | 185 | + log.debug("isEdgeDevice for device{} is {}", |
98 | - return true; | 186 | + deviceId, |
187 | + deviceConfigMap.get(deviceId).isEdge); | ||
188 | + return deviceConfigMap.get(deviceId).isEdge; | ||
189 | + } else { | ||
190 | + throw new IllegalStateException(); | ||
99 | } | 191 | } |
100 | - | ||
101 | - return false; | ||
102 | } | 192 | } |
103 | 193 | ||
194 | + /** | ||
195 | + * Returns the segment ids of all configured segment routers. | ||
196 | + * | ||
197 | + * @return list of segment ids | ||
198 | + */ | ||
104 | @Override | 199 | @Override |
105 | public List<Integer> getAllDeviceSegmentIds() { | 200 | public List<Integer> getAllDeviceSegmentIds() { |
106 | return allSegmentIds; | 201 | return allSegmentIds; |
107 | } | 202 | } |
108 | 203 | ||
109 | - | ||
110 | /** | 204 | /** |
111 | - * Returns Segment ID for the router with the MAC address given. | 205 | + * Returns the device identifier or data plane identifier (dpid) |
206 | + * of a segment router given its segment id. | ||
112 | * | 207 | * |
113 | - * @param targetMac Mac address for the router | 208 | + * @param sid segment id |
114 | - * @return Segment ID for the router with the MAC address | 209 | + * @return deviceId device identifier |
115 | */ | 210 | */ |
116 | - public int getSegmentId(MacAddress targetMac) { | 211 | + public DeviceId getDeviceId(int sid) { |
117 | - for (Map.Entry<DeviceId, MacAddress> entry: deviceMacMap.entrySet()) { | 212 | + for (Map.Entry<DeviceId, SegmentRouterInfo> entry: |
118 | - if (entry.getValue().equals(targetMac)) { | 213 | + deviceConfigMap.entrySet()) { |
119 | - return deviceSegmentIdMap.get(entry.getKey()); | 214 | + if (entry.getValue().nodeSid == sid) { |
215 | + return entry.getValue().deviceId; | ||
120 | } | 216 | } |
121 | } | 217 | } |
122 | 218 | ||
123 | - return -1; | 219 | + return null; |
124 | } | 220 | } |
125 | 221 | ||
126 | /** | 222 | /** |
127 | - * Returns Segment ID for the router withe IP address given. | 223 | + * Returns the device identifier or data plane identifier (dpid) |
224 | + * of a segment router given its router ip address. | ||
128 | * | 225 | * |
129 | - * @param targetAddress IP address of the router | 226 | + * @param ipAddress router ip address |
130 | - * @return Segment ID for the router with the IP address | 227 | + * @return deviceId device identifier |
131 | */ | 228 | */ |
132 | - public int getSegmentId(Ip4Address targetAddress) { | 229 | + public DeviceId getDeviceId(Ip4Address ipAddress) { |
133 | - for (Map.Entry<DeviceId, Ip4Address> entry: deviceIpMap.entrySet()) { | 230 | + for (Map.Entry<DeviceId, SegmentRouterInfo> entry: |
134 | - if (entry.getValue().equals(targetAddress)) { | 231 | + deviceConfigMap.entrySet()) { |
135 | - return deviceSegmentIdMap.get(entry.getKey()); | 232 | + if (entry.getValue().ip.equals(ipAddress)) { |
233 | + return entry.getValue().deviceId; | ||
136 | } | 234 | } |
137 | } | 235 | } |
138 | 236 | ||
139 | - return -1; | 237 | + return null; |
140 | } | 238 | } |
141 | 239 | ||
142 | /** | 240 | /** |
143 | - * Returns Router IP address for the router with the device ID given. | 241 | + * Returns the configured subnet gateway ip addresses for a segment router. |
144 | * | 242 | * |
145 | - * @param deviceId device ID of the router | 243 | + * @param deviceId device identifier |
146 | - * @return IP address of the router | 244 | + * @return list of ip addresses |
147 | */ | 245 | */ |
148 | - public Ip4Address getRouterIp(DeviceId deviceId) { | 246 | + public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) { |
149 | - if (deviceIpMap.get(deviceId) != null) { | 247 | + if (deviceConfigMap.get(deviceId) != null) { |
150 | - log.debug("getDeviceIp for device{} is {}", | 248 | + log.debug("getSubnetGatewayIps for device{} is {}", |
151 | deviceId, | 249 | deviceId, |
152 | - deviceIpMap.get(deviceId)); | 250 | + deviceConfigMap.get(deviceId).gatewayIps.values()); |
153 | - return deviceIpMap.get(deviceId); | 251 | + return new ArrayList<Ip4Address>(deviceConfigMap. |
252 | + get(deviceId).gatewayIps.values()); | ||
154 | } else { | 253 | } else { |
155 | - throw new IllegalStateException(); | 254 | + return null; |
156 | } | 255 | } |
157 | } | 256 | } |
158 | 257 | ||
159 | /** | 258 | /** |
160 | - * Returns the Device ID of the router with the Segment ID given. | 259 | + * Returns the configured subnet prefixes for a segment router. |
161 | * | 260 | * |
162 | - * @param sid Segment ID of the router | 261 | + * @param deviceId device identifier |
163 | - * @return Device ID of the router | 262 | + * @return list of ip prefixes |
164 | */ | 263 | */ |
165 | - public DeviceId getDeviceId(int sid) { | 264 | + public List<Ip4Prefix> getSubnets(DeviceId deviceId) { |
166 | - for (Map.Entry<DeviceId, Integer> entry: deviceSegmentIdMap.entrySet()) { | 265 | + if (deviceConfigMap.get(deviceId) != null) { |
167 | - if (entry.getValue() == sid) { | 266 | + log.debug("getSubnets for device{} is {}", |
168 | - return entry.getKey(); | 267 | + deviceId, |
268 | + deviceConfigMap.get(deviceId).subnets.values()); | ||
269 | + return new ArrayList<Ip4Prefix>(deviceConfigMap. | ||
270 | + get(deviceId).subnets.values()); | ||
271 | + } else { | ||
272 | + return null; | ||
169 | } | 273 | } |
170 | } | 274 | } |
171 | 275 | ||
276 | + /** | ||
277 | + * Returns the router ip address of segment router that has the | ||
278 | + * specified ip address in its subnets. | ||
279 | + * | ||
280 | + * @param destIpAddress target ip address | ||
281 | + * @return router ip address | ||
282 | + */ | ||
283 | + public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) { | ||
284 | + for (Map.Entry<DeviceId, SegmentRouterInfo> entry: | ||
285 | + deviceConfigMap.entrySet()) { | ||
286 | + for (Ip4Prefix prefix:entry.getValue().subnets.values()) { | ||
287 | + if (prefix.contains(destIpAddress)) { | ||
288 | + return entry.getValue().ip; | ||
289 | + } | ||
290 | + } | ||
291 | + } | ||
292 | + | ||
293 | + log.debug("No router was found for {}", destIpAddress); | ||
172 | return null; | 294 | return null; |
173 | } | 295 | } |
174 | 296 | ||
175 | /** | 297 | /** |
176 | - * Returns the Device ID of the router with the IP address given. | 298 | + * Returns the router mac address of segment router that has the |
299 | + * specified ip address as one of its subnet gateway ip address. | ||
177 | * | 300 | * |
178 | - * @param ipAddress IP address of the router | 301 | + * @param gatewayIpAddress router gateway ip address |
179 | - * @return Device ID of the router | 302 | + * @return router mac address |
180 | */ | 303 | */ |
181 | - public DeviceId getDeviceId(Ip4Address ipAddress) { | 304 | + public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) { |
182 | - for (Map.Entry<DeviceId, Ip4Address> entry: deviceIpMap.entrySet()) { | 305 | + for (Map.Entry<DeviceId, SegmentRouterInfo> entry: |
183 | - if (entry.getValue().equals(ipAddress)) { | 306 | + deviceConfigMap.entrySet()) { |
184 | - return entry.getKey(); | 307 | + if (entry.getValue().gatewayIps. |
308 | + values().contains(gatewayIpAddress)) { | ||
309 | + return entry.getValue().mac; | ||
185 | } | 310 | } |
186 | } | 311 | } |
187 | 312 | ||
313 | + log.debug("Cannot find a router for {}", gatewayIpAddress); | ||
188 | return null; | 314 | return null; |
189 | } | 315 | } |
190 | } | 316 | } | ... | ... |
... | @@ -16,7 +16,7 @@ | ... | @@ -16,7 +16,7 @@ |
16 | package org.onosproject.segmentrouting; | 16 | package org.onosproject.segmentrouting; |
17 | 17 | ||
18 | import java.nio.ByteBuffer; | 18 | import java.nio.ByteBuffer; |
19 | - | 19 | +import java.util.List; |
20 | import org.onlab.packet.Ethernet; | 20 | import org.onlab.packet.Ethernet; |
21 | import org.onlab.packet.ICMP; | 21 | import org.onlab.packet.ICMP; |
22 | import org.onlab.packet.IPv4; | 22 | import org.onlab.packet.IPv4; |
... | @@ -69,14 +69,14 @@ public class IcmpHandler { | ... | @@ -69,14 +69,14 @@ public class IcmpHandler { |
69 | DeviceId deviceId = connectPoint.deviceId(); | 69 | DeviceId deviceId = connectPoint.deviceId(); |
70 | Ip4Address destinationAddress = | 70 | Ip4Address destinationAddress = |
71 | Ip4Address.valueOf(ipv4.getDestinationAddress()); | 71 | Ip4Address.valueOf(ipv4.getDestinationAddress()); |
72 | - Ip4Address gatewayIpAddress = config.getGatewayIpAddress(deviceId); | 72 | + List<Ip4Address> gatewayIpAddresses = config.getGatewayIpAddress(deviceId); |
73 | IpPrefix routerIpPrefix = config.getRouterIpAddress(deviceId); | 73 | IpPrefix routerIpPrefix = config.getRouterIpAddress(deviceId); |
74 | Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address(); | 74 | Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address(); |
75 | 75 | ||
76 | // ICMP to the router IP or gateway IP | 76 | // ICMP to the router IP or gateway IP |
77 | if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST && | 77 | if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST && |
78 | (destinationAddress.equals(routerIpAddress) || | 78 | (destinationAddress.equals(routerIpAddress) || |
79 | - gatewayIpAddress.equals(destinationAddress))) { | 79 | + gatewayIpAddresses.contains(destinationAddress))) { |
80 | sendICMPResponse(ethernet, connectPoint); | 80 | sendICMPResponse(ethernet, connectPoint); |
81 | // TODO: do we need to set the flow rule again ?? | 81 | // TODO: do we need to set the flow rule again ?? |
82 | 82 | ... | ... |
... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
16 | package org.onosproject.segmentrouting; | 16 | package org.onosproject.segmentrouting; |
17 | 17 | ||
18 | import com.google.common.collect.Lists; | 18 | import com.google.common.collect.Lists; |
19 | + | ||
19 | import org.onlab.packet.Ip4Address; | 20 | import org.onlab.packet.Ip4Address; |
20 | import org.onlab.packet.Ip4Prefix; | 21 | import org.onlab.packet.Ip4Prefix; |
21 | import org.onlab.packet.IpPrefix; | 22 | import org.onlab.packet.IpPrefix; |
... | @@ -26,39 +27,33 @@ import org.onosproject.net.PortNumber; | ... | @@ -26,39 +27,33 @@ import org.onosproject.net.PortNumber; |
26 | import org.slf4j.Logger; | 27 | import org.slf4j.Logger; |
27 | import org.slf4j.LoggerFactory; | 28 | import org.slf4j.LoggerFactory; |
28 | 29 | ||
29 | -import java.net.URI; | ||
30 | import java.util.List; | 30 | import java.util.List; |
31 | import java.util.Set; | 31 | import java.util.Set; |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * This class is temporary class and used only for test. | 34 | * This class is temporary class and used only for test. |
35 | * It will be replaced with "real" Network Config Manager. | 35 | * It will be replaced with "real" Network Config Manager. |
36 | + * | ||
37 | + * TODO: Knock off this wrapper and directly use DeviceConfiguration class | ||
36 | */ | 38 | */ |
37 | 39 | ||
38 | public class NetworkConfigHandler { | 40 | public class NetworkConfigHandler { |
39 | 41 | ||
40 | private static Logger log = LoggerFactory.getLogger(NetworkConfigHandler.class); | 42 | private static Logger log = LoggerFactory.getLogger(NetworkConfigHandler.class); |
41 | private SegmentRoutingManager srManager; | 43 | private SegmentRoutingManager srManager; |
42 | - private DeviceConfiguration deviceConfig = new DeviceConfiguration(); | 44 | + private DeviceConfiguration deviceConfig; |
43 | 45 | ||
44 | - public NetworkConfigHandler(SegmentRoutingManager srManager) { | 46 | + public NetworkConfigHandler(SegmentRoutingManager srManager, |
47 | + DeviceConfiguration deviceConfig) { | ||
45 | this.srManager = srManager; | 48 | this.srManager = srManager; |
49 | + this.deviceConfig = deviceConfig; | ||
46 | } | 50 | } |
47 | 51 | ||
48 | - public Ip4Address getGatewayIpAddress(DeviceId deviceId) { | 52 | + public List<Ip4Address> getGatewayIpAddress(DeviceId deviceId) { |
49 | - | 53 | + return this.deviceConfig.getSubnetGatewayIps(deviceId); |
50 | - if (deviceId.uri().equals(URI.create("of:0000000000000001"))) { | ||
51 | - return Ip4Address.valueOf("10.0.1.128"); | ||
52 | - } else if (deviceId.uri().equals(URI.create("of:0000000000000006"))) { | ||
53 | - return Ip4Address.valueOf("7.7.7.128"); | ||
54 | - } | ||
55 | - | ||
56 | - log.warn("No gateway Ip address was found for {}", deviceId); | ||
57 | - return Ip4Address.valueOf("0.0.0.0"); | ||
58 | } | 54 | } |
59 | 55 | ||
60 | public IpPrefix getRouterIpAddress(DeviceId deviceId) { | 56 | public IpPrefix getRouterIpAddress(DeviceId deviceId) { |
61 | - | ||
62 | return IpPrefix.valueOf(deviceConfig.getRouterIp(deviceId), 32); | 57 | return IpPrefix.valueOf(deviceConfig.getRouterIp(deviceId), 32); |
63 | } | 58 | } |
64 | 59 | ||
... | @@ -68,17 +63,13 @@ public class NetworkConfigHandler { | ... | @@ -68,17 +63,13 @@ public class NetworkConfigHandler { |
68 | 63 | ||
69 | public boolean inSameSubnet(DeviceId deviceId, Ip4Address destIp) { | 64 | public boolean inSameSubnet(DeviceId deviceId, Ip4Address destIp) { |
70 | 65 | ||
71 | - String subnetInfo = getSubnetInfo(deviceId); | 66 | + List<Ip4Prefix> subnets = getSubnetInfo(deviceId); |
72 | - if (subnetInfo == null) { | 67 | + if (subnets == null) { |
73 | return false; | 68 | return false; |
74 | } | 69 | } |
75 | 70 | ||
76 | - IpPrefix prefix = IpPrefix.valueOf(subnetInfo); | 71 | + return subnets.stream() |
77 | - if (prefix.contains(destIp)) { | 72 | + .anyMatch((subnet) -> subnet.contains(destIp)); |
78 | - return true; | ||
79 | - } | ||
80 | - | ||
81 | - return false; | ||
82 | } | 73 | } |
83 | 74 | ||
84 | public boolean inSameSubnet(Ip4Address address, int sid) { | 75 | public boolean inSameSubnet(Ip4Address address, int sid) { |
... | @@ -88,43 +79,23 @@ public class NetworkConfigHandler { | ... | @@ -88,43 +79,23 @@ public class NetworkConfigHandler { |
88 | return false; | 79 | return false; |
89 | } | 80 | } |
90 | 81 | ||
91 | - String subnetInfo = getSubnetInfo(deviceId); | 82 | + return inSameSubnet(deviceId, address); |
92 | - if (subnetInfo == null) { | ||
93 | - log.warn("Cannot find the subnet info for {}", deviceId); | ||
94 | - return false; | ||
95 | } | 83 | } |
96 | 84 | ||
97 | - Ip4Prefix subnet = Ip4Prefix.valueOf(subnetInfo); | 85 | + public List<Ip4Prefix> getSubnetInfo(DeviceId deviceId) { |
98 | - if (subnet.contains(address)) { | 86 | + return deviceConfig.getSubnets(deviceId); |
99 | - return true; | ||
100 | - } | ||
101 | - | ||
102 | - return false; | ||
103 | - | ||
104 | - } | ||
105 | - | ||
106 | - public String getSubnetInfo(DeviceId deviceId) { | ||
107 | - // TODO : supports multiple subnet | ||
108 | - if (deviceId.uri().equals(URI.create("of:0000000000000001"))) { | ||
109 | - return "10.0.1.1/24"; | ||
110 | - } else if (deviceId.uri().equals(URI.create("of:0000000000000006"))) { | ||
111 | - return "7.7.7.7/24"; | ||
112 | - } else { | ||
113 | - log.error("Switch {} is not an edge router", deviceId); | ||
114 | - return null; | ||
115 | - } | ||
116 | } | 87 | } |
117 | 88 | ||
118 | public int getMplsId(DeviceId deviceId) { | 89 | public int getMplsId(DeviceId deviceId) { |
119 | return deviceConfig.getSegmentId(deviceId); | 90 | return deviceConfig.getSegmentId(deviceId); |
120 | } | 91 | } |
121 | 92 | ||
122 | - public int getMplsId(MacAddress mac) { | 93 | + public int getMplsId(MacAddress routerMac) { |
123 | - return deviceConfig.getSegmentId(mac); | 94 | + return deviceConfig.getSegmentId(routerMac); |
124 | } | 95 | } |
125 | 96 | ||
126 | - public int getMplsId(Ip4Address address) { | 97 | + public int getMplsId(Ip4Address routerIpAddress) { |
127 | - return deviceConfig.getSegmentId(address); | 98 | + return deviceConfig.getSegmentId(routerIpAddress); |
128 | } | 99 | } |
129 | 100 | ||
130 | public boolean isEcmpNotSupportedInTransit(DeviceId deviceId) { | 101 | public boolean isEcmpNotSupportedInTransit(DeviceId deviceId) { |
... | @@ -132,17 +103,12 @@ public class NetworkConfigHandler { | ... | @@ -132,17 +103,12 @@ public class NetworkConfigHandler { |
132 | } | 103 | } |
133 | 104 | ||
134 | public boolean isTransitRouter(DeviceId deviceId) { | 105 | public boolean isTransitRouter(DeviceId deviceId) { |
135 | - return true; | 106 | + return !(deviceConfig.isEdgeDevice(deviceId)); |
136 | } | 107 | } |
137 | 108 | ||
138 | 109 | ||
139 | public boolean isEdgeRouter(DeviceId deviceId) { | 110 | public boolean isEdgeRouter(DeviceId deviceId) { |
140 | - if (deviceId.uri().equals(URI.create("of:0000000000000001")) | 111 | + return deviceConfig.isEdgeDevice(deviceId); |
141 | - || deviceId.uri().equals(URI.create("of:0000000000000006"))) { | ||
142 | - return true; | ||
143 | - } | ||
144 | - | ||
145 | - return false; | ||
146 | } | 112 | } |
147 | 113 | ||
148 | private List<PortNumber> getPortsToNeighbors(DeviceId deviceId, List<DeviceId> fwdSws) { | 114 | private List<PortNumber> getPortsToNeighbors(DeviceId deviceId, List<DeviceId> fwdSws) { |
... | @@ -177,16 +143,7 @@ public class NetworkConfigHandler { | ... | @@ -177,16 +143,7 @@ public class NetworkConfigHandler { |
177 | 143 | ||
178 | 144 | ||
179 | public Ip4Address getDestinationRouterAddress(Ip4Address destIpAddress) { | 145 | public Ip4Address getDestinationRouterAddress(Ip4Address destIpAddress) { |
180 | - // TODO: need to check the subnet info | 146 | + return deviceConfig.getRouterIpAddressForASubnetHost(destIpAddress); |
181 | - if (destIpAddress.toString().equals("10.0.1.1")) { | ||
182 | - return Ip4Address.valueOf("192.168.0.1"); | ||
183 | - } else if (destIpAddress.toString().equals("7.7.7.7")) { | ||
184 | - return Ip4Address.valueOf("192.168.0.6"); | ||
185 | - } else { | ||
186 | - log.warn("No router was found for {}", destIpAddress); | ||
187 | - return null; | ||
188 | - } | ||
189 | - | ||
190 | } | 147 | } |
191 | 148 | ||
192 | public DeviceId getDeviceId(Ip4Address ip4Address) { | 149 | public DeviceId getDeviceId(Ip4Address ip4Address) { |
... | @@ -194,13 +151,6 @@ public class NetworkConfigHandler { | ... | @@ -194,13 +151,6 @@ public class NetworkConfigHandler { |
194 | } | 151 | } |
195 | 152 | ||
196 | public MacAddress getRouterMac(Ip4Address targetAddress) { | 153 | public MacAddress getRouterMac(Ip4Address targetAddress) { |
197 | - if (targetAddress.toString().equals("10.0.1.128")) { | 154 | + return deviceConfig.getRouterMacForAGatewayIp(targetAddress); |
198 | - return MacAddress.valueOf("00:00:00:00:00:01"); | ||
199 | - } else if (targetAddress.toString().equals("7.7.7.128")) { | ||
200 | - return MacAddress.valueOf("00:00:00:00:00:06"); | ||
201 | - } else { | ||
202 | - log.warn("Cannot find a router for {}", targetAddress); | ||
203 | - return null; | ||
204 | - } | ||
205 | } | 155 | } |
206 | } | 156 | } | ... | ... |
... | @@ -17,11 +17,11 @@ package org.onosproject.segmentrouting; | ... | @@ -17,11 +17,11 @@ package org.onosproject.segmentrouting; |
17 | 17 | ||
18 | import org.onlab.packet.Ethernet; | 18 | import org.onlab.packet.Ethernet; |
19 | import org.onlab.packet.Ip4Address; | 19 | import org.onlab.packet.Ip4Address; |
20 | +import org.onlab.packet.Ip4Prefix; | ||
20 | import org.onlab.packet.IpPrefix; | 21 | import org.onlab.packet.IpPrefix; |
21 | import org.onlab.packet.MacAddress; | 22 | import org.onlab.packet.MacAddress; |
22 | - | ||
23 | import org.onlab.packet.MplsLabel; | 23 | import org.onlab.packet.MplsLabel; |
24 | -import org.onosproject.grouphandler.NeighborSet; | 24 | +import org.onosproject.segmentrouting.grouphandler.NeighborSet; |
25 | import org.onosproject.net.DeviceId; | 25 | import org.onosproject.net.DeviceId; |
26 | import org.onosproject.net.Link; | 26 | import org.onosproject.net.Link; |
27 | import org.onosproject.net.PortNumber; | 27 | import org.onosproject.net.PortNumber; |
... | @@ -94,15 +94,15 @@ public class RoutingRulePopulator { | ... | @@ -94,15 +94,15 @@ public class RoutingRulePopulator { |
94 | * Populates IP flow rules for the subnets of the destination router. | 94 | * Populates IP flow rules for the subnets of the destination router. |
95 | * | 95 | * |
96 | * @param deviceId switch ID to set the rules | 96 | * @param deviceId switch ID to set the rules |
97 | - * @param subnetInfo subnet information | 97 | + * @param subnets subnet information |
98 | * @param destSw destination switch ID | 98 | * @param destSw destination switch ID |
99 | * @param nextHops next hop switch ID list | 99 | * @param nextHops next hop switch ID list |
100 | * @return true if all rules are set successfully, false otherwise | 100 | * @return true if all rules are set successfully, false otherwise |
101 | */ | 101 | */ |
102 | - public boolean populateIpRuleForSubnet(DeviceId deviceId, String subnetInfo, | 102 | + public boolean populateIpRuleForSubnet(DeviceId deviceId, List<Ip4Prefix> subnets, |
103 | DeviceId destSw, Set<DeviceId> nextHops) { | 103 | DeviceId destSw, Set<DeviceId> nextHops) { |
104 | 104 | ||
105 | - List<IpPrefix> subnets = extractSubnet(subnetInfo); | 105 | + //List<IpPrefix> subnets = extractSubnet(subnetInfo); |
106 | for (IpPrefix subnet: subnets) { | 106 | for (IpPrefix subnet: subnets) { |
107 | if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) { | 107 | if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) { |
108 | return false; | 108 | return false; |
... | @@ -371,21 +371,6 @@ public class RoutingRulePopulator { | ... | @@ -371,21 +371,6 @@ public class RoutingRulePopulator { |
371 | 371 | ||
372 | } | 372 | } |
373 | 373 | ||
374 | - | ||
375 | - private List<IpPrefix> extractSubnet(String subnetInfo) { | ||
376 | - List<IpPrefix> subnetIpPrefixes = new ArrayList<>(); | ||
377 | - | ||
378 | - // TODO: refactoring required depending on the format of the subnet info | ||
379 | - IpPrefix prefix = IpPrefix.valueOf(subnetInfo); | ||
380 | - if (prefix == null) { | ||
381 | - log.error("Wrong ip prefix type {}", subnetInfo); | ||
382 | - } else { | ||
383 | - subnetIpPrefixes.add(prefix); | ||
384 | - } | ||
385 | - | ||
386 | - return subnetIpPrefixes; | ||
387 | - } | ||
388 | - | ||
389 | private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) { | 374 | private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) { |
390 | 375 | ||
391 | Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId); | 376 | Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId); | ... | ... |
... | @@ -25,8 +25,8 @@ import org.onlab.packet.IPv4; | ... | @@ -25,8 +25,8 @@ import org.onlab.packet.IPv4; |
25 | import org.onosproject.core.ApplicationId; | 25 | import org.onosproject.core.ApplicationId; |
26 | import org.onosproject.core.CoreService; | 26 | import org.onosproject.core.CoreService; |
27 | import org.onosproject.event.Event; | 27 | import org.onosproject.event.Event; |
28 | -import org.onosproject.grouphandler.DefaultGroupHandler; | 28 | +import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; |
29 | -import org.onosproject.grouphandler.NeighborSet; | 29 | +import org.onosproject.segmentrouting.grouphandler.NeighborSet; |
30 | import org.onosproject.mastership.MastershipService; | 30 | import org.onosproject.mastership.MastershipService; |
31 | import org.onosproject.net.Device; | 31 | import org.onosproject.net.Device; |
32 | import org.onosproject.net.DeviceId; | 32 | import org.onosproject.net.DeviceId; |
... | @@ -52,6 +52,7 @@ import org.onosproject.net.packet.PacketContext; | ... | @@ -52,6 +52,7 @@ import org.onosproject.net.packet.PacketContext; |
52 | import org.onosproject.net.packet.PacketProcessor; | 52 | import org.onosproject.net.packet.PacketProcessor; |
53 | import org.onosproject.net.packet.PacketService; | 53 | import org.onosproject.net.packet.PacketService; |
54 | import org.onosproject.net.topology.TopologyService; | 54 | import org.onosproject.net.topology.TopologyService; |
55 | +import org.onosproject.segmentrouting.config.NetworkConfigManager; | ||
55 | import org.slf4j.Logger; | 56 | import org.slf4j.Logger; |
56 | import org.slf4j.LoggerFactory; | 57 | import org.slf4j.LoggerFactory; |
57 | 58 | ||
... | @@ -98,16 +99,15 @@ public class SegmentRoutingManager { | ... | @@ -98,16 +99,15 @@ public class SegmentRoutingManager { |
98 | 99 | ||
99 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 100 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
100 | protected MastershipService mastershipService; | 101 | protected MastershipService mastershipService; |
101 | - | 102 | + protected NetworkConfigHandler networkConfigHandler = null; |
102 | - protected NetworkConfigHandler networkConfigHandler = new NetworkConfigHandler(this); | 103 | + protected ArpHandler arpHandler = null; |
103 | - protected ArpHandler arpHandler = new ArpHandler(this); | 104 | + protected IcmpHandler icmpHandler = null; |
104 | - protected IcmpHandler icmpHandler = new IcmpHandler(this); | 105 | + protected IpHandler ipHandler = null; |
105 | - protected IpHandler ipHandler = new IpHandler(this); | 106 | + protected RoutingRulePopulator routingRulePopulator = null; |
106 | - protected RoutingRulePopulator routingRulePopulator = new RoutingRulePopulator(this); | ||
107 | protected ApplicationId appId; | 107 | protected ApplicationId appId; |
108 | 108 | ||
109 | - private DefaultRoutingHandler defaultRoutingHandler = new DefaultRoutingHandler(this); | 109 | + private DefaultRoutingHandler defaultRoutingHandler = null; |
110 | - private DeviceConfiguration deviceConfiguration = new DeviceConfiguration(); | 110 | + private DeviceConfiguration deviceConfiguration = null; |
111 | private InternalPacketProcessor processor = new InternalPacketProcessor(); | 111 | private InternalPacketProcessor processor = new InternalPacketProcessor(); |
112 | private InternalEventHandler eventHandler = new InternalEventHandler(); | 112 | private InternalEventHandler eventHandler = new InternalEventHandler(); |
113 | 113 | ||
... | @@ -118,6 +118,8 @@ public class SegmentRoutingManager { | ... | @@ -118,6 +118,8 @@ public class SegmentRoutingManager { |
118 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap | 118 | private Map<DeviceId, DefaultGroupHandler> groupHandlerMap |
119 | = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); | 119 | = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); |
120 | 120 | ||
121 | + private NetworkConfigManager networkConfigService = new NetworkConfigManager();; | ||
122 | + | ||
121 | private static int numOfEvents = 0; | 123 | private static int numOfEvents = 0; |
122 | private static int numOfHandlerExecution = 0; | 124 | private static int numOfHandlerExecution = 0; |
123 | private static int numOfHandlerScheduled = 0; | 125 | private static int numOfHandlerScheduled = 0; |
... | @@ -125,6 +127,16 @@ public class SegmentRoutingManager { | ... | @@ -125,6 +127,16 @@ public class SegmentRoutingManager { |
125 | @Activate | 127 | @Activate |
126 | protected void activate() { | 128 | protected void activate() { |
127 | appId = coreService.registerApplication("org.onosproject.segmentrouting"); | 129 | appId = coreService.registerApplication("org.onosproject.segmentrouting"); |
130 | + networkConfigService.init(); | ||
131 | + deviceConfiguration = new DeviceConfiguration(networkConfigService); | ||
132 | + networkConfigHandler = new NetworkConfigHandler(this, | ||
133 | + deviceConfiguration); | ||
134 | + arpHandler = new ArpHandler(this); | ||
135 | + icmpHandler = new IcmpHandler(this); | ||
136 | + ipHandler = new IpHandler(this); | ||
137 | + routingRulePopulator = new RoutingRulePopulator(this); | ||
138 | + defaultRoutingHandler = new DefaultRoutingHandler(this); | ||
139 | + | ||
128 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); | 140 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); |
129 | linkService.addListener(new InternalLinkListener()); | 141 | linkService.addListener(new InternalLinkListener()); |
130 | groupService.addListener(new InternalGroupListener()); | 142 | groupService.addListener(new InternalGroupListener()); |
... | @@ -271,6 +283,7 @@ public class SegmentRoutingManager { | ... | @@ -271,6 +283,7 @@ public class SegmentRoutingManager { |
271 | 283 | ||
272 | private class InternalEventHandler implements Runnable { | 284 | private class InternalEventHandler implements Runnable { |
273 | 285 | ||
286 | + @Override | ||
274 | public void run() { | 287 | public void run() { |
275 | numOfHandlerExecution++; | 288 | numOfHandlerExecution++; |
276 | while (!eventQueue.isEmpty()) { | 289 | while (!eventQueue.isEmpty()) { |
... | @@ -326,7 +339,11 @@ public class SegmentRoutingManager { | ... | @@ -326,7 +339,11 @@ public class SegmentRoutingManager { |
326 | log.debug("A new device with ID {} was added", device.id()); | 339 | log.debug("A new device with ID {} was added", device.id()); |
327 | defaultRoutingHandler.populateTtpRules(device.id()); | 340 | defaultRoutingHandler.populateTtpRules(device.id()); |
328 | DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler( | 341 | DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler( |
329 | - device.id(), appId, new DeviceConfiguration(), linkService, groupService); | 342 | + device.id(), |
343 | + appId, | ||
344 | + deviceConfiguration, | ||
345 | + linkService, | ||
346 | + groupService); | ||
330 | dgh.createGroups(); | 347 | dgh.createGroups(); |
331 | groupHandlerMap.put(device.id(), dgh); | 348 | groupHandlerMap.put(device.id(), dgh); |
332 | } | 349 | } | ... | ... |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/NetworkConfig.java
0 → 100644
1 | +package org.onosproject.segmentrouting.config; | ||
2 | + | ||
3 | +import java.util.ArrayList; | ||
4 | +import java.util.List; | ||
5 | +import java.util.Map; | ||
6 | + | ||
7 | +import org.onosproject.net.DeviceId; | ||
8 | +import org.slf4j.Logger; | ||
9 | +import org.slf4j.LoggerFactory; | ||
10 | + | ||
11 | +import com.fasterxml.jackson.annotation.JsonProperty; | ||
12 | +import com.fasterxml.jackson.databind.JsonNode; | ||
13 | + | ||
14 | +/** | ||
15 | + * Public class corresponding to JSON described data model. Defines the network | ||
16 | + * configuration at startup. | ||
17 | + */ | ||
18 | +public class NetworkConfig { | ||
19 | + protected static final Logger log = LoggerFactory.getLogger(NetworkConfig.class); | ||
20 | + | ||
21 | + @SuppressWarnings("unused") | ||
22 | + private String comment; | ||
23 | + | ||
24 | + private Boolean restrictSwitches; | ||
25 | + private Boolean restrictLinks; | ||
26 | + private List<SwitchConfig> switches; | ||
27 | + private List<LinkConfig> links; | ||
28 | + | ||
29 | + /** | ||
30 | + * Default constructor. | ||
31 | + */ | ||
32 | + public NetworkConfig() { | ||
33 | + switches = new ArrayList<SwitchConfig>(); | ||
34 | + links = new ArrayList<LinkConfig>(); | ||
35 | + } | ||
36 | + | ||
37 | + @JsonProperty("comment") | ||
38 | + public void setComment(String c) { | ||
39 | + log.trace("NetworkConfig: comment={}", c); | ||
40 | + comment = c; | ||
41 | + } | ||
42 | + | ||
43 | + @JsonProperty("restrictSwitches") | ||
44 | + public void setRestrictSwitches(boolean rs) { | ||
45 | + log.trace("NetworkConfig: restrictSwitches={}", rs); | ||
46 | + restrictSwitches = rs; | ||
47 | + } | ||
48 | + | ||
49 | + /** | ||
50 | + * Returns default restrict configuration for switches. | ||
51 | + * | ||
52 | + * @return boolean | ||
53 | + */ | ||
54 | + public Boolean getRestrictSwitches() { | ||
55 | + return restrictSwitches; | ||
56 | + } | ||
57 | + | ||
58 | + @JsonProperty("restrictLinks") | ||
59 | + public void setRestrictLinks(boolean rl) { | ||
60 | + log.trace("NetworkConfig: restrictLinks={}", rl); | ||
61 | + restrictLinks = rl; | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * Returns default restrict configuration for links. | ||
66 | + * | ||
67 | + * @return boolean | ||
68 | + */ | ||
69 | + public Boolean getRestrictLinks() { | ||
70 | + return restrictLinks; | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Returns configuration for switches. | ||
75 | + * | ||
76 | + * @return list of switch configuration | ||
77 | + */ | ||
78 | + public List<SwitchConfig> getSwitchConfig() { | ||
79 | + return switches; | ||
80 | + } | ||
81 | + | ||
82 | + @JsonProperty("switchConfig") | ||
83 | + public void setSwitchConfig(List<SwitchConfig> switches2) { | ||
84 | + log.trace("NetworkConfig: switchConfig={}", switches2); | ||
85 | + this.switches = switches2; | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
89 | + * Java class corresponding to JSON described switch | ||
90 | + * configuration data model. | ||
91 | + */ | ||
92 | + public static class SwitchConfig { | ||
93 | + protected String nodeDpid; | ||
94 | + protected String name; | ||
95 | + protected String type; | ||
96 | + protected boolean allowed; | ||
97 | + protected double latitude; | ||
98 | + protected double longitude; | ||
99 | + protected Map<String, JsonNode> params; | ||
100 | + protected Map<String, String> publishAttributes; | ||
101 | + protected DeviceId dpid; | ||
102 | + | ||
103 | + /** | ||
104 | + * Returns the configured "name" of a switch. | ||
105 | + * | ||
106 | + * @return string | ||
107 | + */ | ||
108 | + public String getName() { | ||
109 | + return name; | ||
110 | + } | ||
111 | + | ||
112 | + @JsonProperty("name") | ||
113 | + public void setName(String name) { | ||
114 | + log.trace("SwitchConfig: name={}", name); | ||
115 | + this.name = name; | ||
116 | + } | ||
117 | + | ||
118 | + /** | ||
119 | + * Returns the data plane identifier of a switch. | ||
120 | + * | ||
121 | + * @return ONOS device identifier | ||
122 | + */ | ||
123 | + public DeviceId getDpid() { | ||
124 | + return dpid; | ||
125 | + } | ||
126 | + | ||
127 | + public void setDpid(DeviceId dpid) { | ||
128 | + this.dpid = dpid; | ||
129 | + this.nodeDpid = dpid.toString(); | ||
130 | + } | ||
131 | + | ||
132 | + /** | ||
133 | + * Returns the data plane identifier of a switch. | ||
134 | + * | ||
135 | + * @return string | ||
136 | + */ | ||
137 | + public String getNodeDpid() { | ||
138 | + return nodeDpid; | ||
139 | + } | ||
140 | + | ||
141 | + // mapper sets both DeviceId and string fields for dpid | ||
142 | + @JsonProperty("nodeDpid") | ||
143 | + public void setNodeDpid(String nodeDpid) { | ||
144 | + log.trace("SwitchConfig: nodeDpid={}", nodeDpid); | ||
145 | + this.nodeDpid = nodeDpid; | ||
146 | + this.dpid = DeviceId.deviceId(nodeDpid); | ||
147 | + } | ||
148 | + | ||
149 | + /** | ||
150 | + * Returns the type of a switch. | ||
151 | + * | ||
152 | + * @return string | ||
153 | + */ | ||
154 | + public String getType() { | ||
155 | + return type; | ||
156 | + } | ||
157 | + | ||
158 | + @JsonProperty("type") | ||
159 | + public void setType(String type) { | ||
160 | + log.trace("SwitchConfig: type={}", type); | ||
161 | + this.type = type; | ||
162 | + } | ||
163 | + | ||
164 | + /** | ||
165 | + * Returns the latitude of a switch. | ||
166 | + * | ||
167 | + * @return double | ||
168 | + */ | ||
169 | + public double getLatitude() { | ||
170 | + return latitude; | ||
171 | + } | ||
172 | + | ||
173 | + @JsonProperty("latitude") | ||
174 | + public void setLatitude(double latitude) { | ||
175 | + log.trace("SwitchConfig: latitude={}", latitude); | ||
176 | + this.latitude = latitude; | ||
177 | + } | ||
178 | + | ||
179 | + /** | ||
180 | + * Returns the longitude of a switch. | ||
181 | + * | ||
182 | + * @return double | ||
183 | + */ | ||
184 | + public double getLongitude() { | ||
185 | + return longitude; | ||
186 | + } | ||
187 | + | ||
188 | + @JsonProperty("longitude") | ||
189 | + public void setLongitude(double longitude) { | ||
190 | + log.trace("SwitchConfig: longitude={}", longitude); | ||
191 | + this.longitude = longitude; | ||
192 | + } | ||
193 | + | ||
194 | + /** | ||
195 | + * Returns the allowed flag for a switch. | ||
196 | + * | ||
197 | + * @return boolean | ||
198 | + */ | ||
199 | + public boolean isAllowed() { | ||
200 | + return allowed; | ||
201 | + } | ||
202 | + | ||
203 | + @JsonProperty("allowed") | ||
204 | + public void setAllowed(boolean allowed) { | ||
205 | + this.allowed = allowed; | ||
206 | + } | ||
207 | + | ||
208 | + /** | ||
209 | + * Returns the additional configured parameters of a switch. | ||
210 | + * | ||
211 | + * @return key value map | ||
212 | + */ | ||
213 | + public Map<String, JsonNode> getParams() { | ||
214 | + return params; | ||
215 | + } | ||
216 | + | ||
217 | + @JsonProperty("params") | ||
218 | + public void setParams(Map<String, JsonNode> params) { | ||
219 | + this.params = params; | ||
220 | + } | ||
221 | + | ||
222 | + /** | ||
223 | + * Reserved for future use. | ||
224 | + * | ||
225 | + * @return key value map | ||
226 | + */ | ||
227 | + public Map<String, String> getPublishAttributes() { | ||
228 | + return publishAttributes; | ||
229 | + } | ||
230 | + | ||
231 | + @JsonProperty("publishAttributes") | ||
232 | + public void setPublishAttributes(Map<String, String> publishAttributes) { | ||
233 | + this.publishAttributes = publishAttributes; | ||
234 | + } | ||
235 | + | ||
236 | + } | ||
237 | + | ||
238 | + @JsonProperty("linkConfig") | ||
239 | + public void setLinkConfig(List<LinkConfig> links2) { | ||
240 | + this.links = links2; | ||
241 | + } | ||
242 | + | ||
243 | + /** | ||
244 | + * Reserved for future use. | ||
245 | + * | ||
246 | + * @return list of configured link configuration | ||
247 | + */ | ||
248 | + public List<LinkConfig> getLinkConfig() { | ||
249 | + return links; | ||
250 | + } | ||
251 | + | ||
252 | + /** | ||
253 | + * Reserved for future use. | ||
254 | + */ | ||
255 | + public static class LinkConfig { | ||
256 | + protected String type; | ||
257 | + protected Boolean allowed; | ||
258 | + protected DeviceId dpid1; | ||
259 | + protected DeviceId dpid2; | ||
260 | + protected String nodeDpid1; | ||
261 | + protected String nodeDpid2; | ||
262 | + protected Map<String, JsonNode> params; | ||
263 | + protected Map<String, String> publishAttributes; | ||
264 | + | ||
265 | + public String getType() { | ||
266 | + return type; | ||
267 | + } | ||
268 | + | ||
269 | + public void setType(String type) { | ||
270 | + this.type = type; | ||
271 | + } | ||
272 | + | ||
273 | + public Boolean isAllowed() { | ||
274 | + return allowed; | ||
275 | + } | ||
276 | + | ||
277 | + public void setAllowed(Boolean allowed) { | ||
278 | + this.allowed = allowed; | ||
279 | + } | ||
280 | + | ||
281 | + public String getNodeDpid1() { | ||
282 | + return nodeDpid1; | ||
283 | + } | ||
284 | + | ||
285 | + // mapper sets both long and string fields for dpid | ||
286 | + public void setNodeDpid1(String nodeDpid1) { | ||
287 | + this.nodeDpid1 = nodeDpid1; | ||
288 | + this.dpid1 = DeviceId.deviceId(nodeDpid1); | ||
289 | + } | ||
290 | + | ||
291 | + public String getNodeDpid2() { | ||
292 | + return nodeDpid2; | ||
293 | + } | ||
294 | + | ||
295 | + // mapper sets both long and string fields for dpid | ||
296 | + public void setNodeDpid2(String nodeDpid2) { | ||
297 | + this.nodeDpid2 = nodeDpid2; | ||
298 | + this.dpid2 = DeviceId.deviceId(nodeDpid2); | ||
299 | + } | ||
300 | + | ||
301 | + public DeviceId getDpid1() { | ||
302 | + return dpid1; | ||
303 | + } | ||
304 | + | ||
305 | + public void setDpid1(DeviceId dpid1) { | ||
306 | + this.dpid1 = dpid1; | ||
307 | + this.nodeDpid1 = dpid1.toString(); | ||
308 | + } | ||
309 | + | ||
310 | + public DeviceId getDpid2() { | ||
311 | + return dpid2; | ||
312 | + } | ||
313 | + | ||
314 | + public void setDpid2(DeviceId dpid2) { | ||
315 | + this.dpid2 = dpid2; | ||
316 | + this.nodeDpid2 = dpid2.toString(); | ||
317 | + } | ||
318 | + | ||
319 | + public Map<String, JsonNode> getParams() { | ||
320 | + return params; | ||
321 | + } | ||
322 | + | ||
323 | + public void setParams(Map<String, JsonNode> params) { | ||
324 | + this.params = params; | ||
325 | + } | ||
326 | + | ||
327 | + public Map<String, String> getPublishAttributes() { | ||
328 | + return publishAttributes; | ||
329 | + } | ||
330 | + | ||
331 | + public void setPublishAttributes(Map<String, String> publishAttributes) { | ||
332 | + this.publishAttributes = publishAttributes; | ||
333 | + } | ||
334 | + } | ||
335 | +} | ||
336 | + |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/NetworkConfigException.java
0 → 100644
1 | +package org.onosproject.segmentrouting.config; | ||
2 | + | ||
3 | +import org.onosproject.net.DeviceId; | ||
4 | +import org.slf4j.Logger; | ||
5 | +import org.slf4j.LoggerFactory; | ||
6 | + | ||
7 | +/** | ||
8 | + * NetworkConfigExceptions specifies a set of unchecked runtime exceptions that | ||
9 | + * can be thrown by the {@link NetworkConfigManager}. It indicates errors that | ||
10 | + * must be fixed in the config file before controller execution can proceed. | ||
11 | + */ | ||
12 | +public class NetworkConfigException extends RuntimeException { | ||
13 | + | ||
14 | + private static final long serialVersionUID = 4959684709803000652L; | ||
15 | + protected static final Logger log = LoggerFactory | ||
16 | + .getLogger(NetworkConfigException.class); | ||
17 | + | ||
18 | + /** | ||
19 | + * Exception for duplicate device identifier configuration. | ||
20 | + */ | ||
21 | + public static class DuplicateDpid extends RuntimeException { | ||
22 | + private static final long serialVersionUID = 5491113234592145335L; | ||
23 | + | ||
24 | + public DuplicateDpid(DeviceId dpid) { | ||
25 | + super(); | ||
26 | + log.error("Duplicate dpid found in switch-config Dpid:{}", | ||
27 | + dpid); | ||
28 | + } | ||
29 | + } | ||
30 | + | ||
31 | + /** | ||
32 | + * Exception for duplicate device name configuration. | ||
33 | + */ | ||
34 | + public static class DuplicateName extends RuntimeException { | ||
35 | + private static final long serialVersionUID = -4090171438031376129L; | ||
36 | + | ||
37 | + public DuplicateName(String name) { | ||
38 | + super(); | ||
39 | + log.error("Duplicate name found in switch-config name:{}", name); | ||
40 | + } | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * Exception for unspecified device identifier for a switch. | ||
45 | + */ | ||
46 | + public static class DpidNotSpecified extends RuntimeException { | ||
47 | + private static final long serialVersionUID = -8494418855597117254L; | ||
48 | + | ||
49 | + public DpidNotSpecified(String name) { | ||
50 | + super(); | ||
51 | + log.error("Dpid not specified for switch-config name:{}", name); | ||
52 | + } | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * Exception for unspecified device name for a switch. | ||
57 | + */ | ||
58 | + public static class NameNotSpecified extends RuntimeException { | ||
59 | + private static final long serialVersionUID = -3518881744110422891L; | ||
60 | + | ||
61 | + public NameNotSpecified(DeviceId dpid) { | ||
62 | + super(); | ||
63 | + log.error("Name not specified for switch-config dpid:{}", | ||
64 | + dpid); | ||
65 | + } | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * Exception for unspecified device type for a switch. | ||
70 | + */ | ||
71 | + public static class SwitchTypeNotSpecified extends RuntimeException { | ||
72 | + private static final long serialVersionUID = 2527453336226053753L; | ||
73 | + | ||
74 | + public SwitchTypeNotSpecified(DeviceId dpid) { | ||
75 | + super(); | ||
76 | + log.error("Switch type not specified for switch-config dpid:{}", | ||
77 | + dpid); | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * Exception for unknown device type configured for a switch. | ||
83 | + */ | ||
84 | + public static class UnknownSwitchType extends RuntimeException { | ||
85 | + private static final long serialVersionUID = 7758418165512249170L; | ||
86 | + | ||
87 | + public UnknownSwitchType(String type, String name) { | ||
88 | + super(); | ||
89 | + log.error("Unknown switch type {} for switch name:{}", type, name); | ||
90 | + } | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * Exception for missing required parameter configuration for a switch. | ||
95 | + */ | ||
96 | + public static class ParamsNotSpecified extends RuntimeException { | ||
97 | + private static final long serialVersionUID = 6247582323691265513L; | ||
98 | + | ||
99 | + public ParamsNotSpecified(String name) { | ||
100 | + super(); | ||
101 | + log.error("Params required - not specified for switch:{}", name); | ||
102 | + } | ||
103 | + } | ||
104 | + | ||
105 | + /** | ||
106 | + * Reserved for future use. | ||
107 | + */ | ||
108 | + public static class LinkTypeNotSpecified extends RuntimeException { | ||
109 | + private static final long serialVersionUID = -2089470389588542215L; | ||
110 | + | ||
111 | + public LinkTypeNotSpecified(String dpid1, String dpid2) { | ||
112 | + super(); | ||
113 | + log.error("Link type not specified for link-config between " | ||
114 | + + "dpid1:{} and dpid2:{}", dpid1, dpid2); | ||
115 | + } | ||
116 | + } | ||
117 | + | ||
118 | + /** | ||
119 | + * Reserved for future use. | ||
120 | + */ | ||
121 | + public static class LinkDpidNotSpecified extends RuntimeException { | ||
122 | + private static final long serialVersionUID = -5701825916378616004L; | ||
123 | + | ||
124 | + public LinkDpidNotSpecified(String dpid1, String dpid2) { | ||
125 | + super(); | ||
126 | + if (dpid1 == null) { | ||
127 | + log.error("nodeDpid1 not specified for link-config "); | ||
128 | + } | ||
129 | + if (dpid2 == null) { | ||
130 | + log.error("nodeDpid2 not specified for link-config "); | ||
131 | + } | ||
132 | + } | ||
133 | + } | ||
134 | + | ||
135 | + /** | ||
136 | + * Reserved for future use. | ||
137 | + */ | ||
138 | + public static class LinkForUnknownSwitchConfig extends RuntimeException { | ||
139 | + private static final long serialVersionUID = -2910458439881964094L; | ||
140 | + | ||
141 | + public LinkForUnknownSwitchConfig(String dpid) { | ||
142 | + super(); | ||
143 | + log.error("Link configuration was specified for a switch-dpid {} " | ||
144 | + + "that has not been configured", dpid); | ||
145 | + } | ||
146 | + } | ||
147 | + | ||
148 | + /** | ||
149 | + * Reserved for future use. | ||
150 | + */ | ||
151 | + public static class UnknownLinkType extends RuntimeException { | ||
152 | + private static final long serialVersionUID = -5505376193106542305L; | ||
153 | + | ||
154 | + public UnknownLinkType(String linktype, String dpid1, String dpid2) { | ||
155 | + super(); | ||
156 | + log.error("unknown link type {} for links between dpid1:{} " | ||
157 | + + "and dpid2:{}", linktype, dpid1, dpid2); | ||
158 | + } | ||
159 | + } | ||
160 | + | ||
161 | + /** | ||
162 | + * Exception for generic configuration errors. | ||
163 | + */ | ||
164 | + public static class ErrorConfig extends RuntimeException { | ||
165 | + private static final long serialVersionUID = -2827406314700193147L; | ||
166 | + | ||
167 | + public ErrorConfig(String errorMsg) { | ||
168 | + super(); | ||
169 | + log.error(errorMsg); | ||
170 | + } | ||
171 | + | ||
172 | + } | ||
173 | + | ||
174 | + /** | ||
175 | + * Reserved for future use. | ||
176 | + */ | ||
177 | + public static class SwitchDpidNotConverted extends RuntimeException { | ||
178 | + private static final long serialVersionUID = 5640347104590170426L; | ||
179 | + | ||
180 | + public SwitchDpidNotConverted(String name) { | ||
181 | + super(); | ||
182 | + log.error("Switch dpid specified as a HexString {} does not match " | ||
183 | + + "with long value", name); | ||
184 | + } | ||
185 | + } | ||
186 | + | ||
187 | + /** | ||
188 | + * Reserved for future use. | ||
189 | + */ | ||
190 | + public static class LinkDpidNotConverted extends RuntimeException { | ||
191 | + private static final long serialVersionUID = 2397245646094080774L; | ||
192 | + | ||
193 | + public LinkDpidNotConverted(String dpid1, String dpid2) { | ||
194 | + log.error("Dpids expressed as HexStrings for links between dpid1:{} " | ||
195 | + + "and dpid2:{} do not match with long values", dpid1, dpid2); | ||
196 | + } | ||
197 | + } | ||
198 | + | ||
199 | +} | ||
200 | + |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/NetworkConfigManager.java
0 → 100644
1 | +package org.onosproject.segmentrouting.config; | ||
2 | + | ||
3 | +import java.io.File; | ||
4 | +import java.io.IOException; | ||
5 | +import java.util.ArrayList; | ||
6 | +import java.util.HashMap; | ||
7 | +import java.util.HashSet; | ||
8 | +import java.util.List; | ||
9 | +import java.util.Map; | ||
10 | +import java.util.Set; | ||
11 | +import java.util.concurrent.ConcurrentHashMap; | ||
12 | +import java.util.concurrent.ConcurrentMap; | ||
13 | + | ||
14 | +import org.onosproject.net.DeviceId; | ||
15 | +import org.onosproject.net.Link; | ||
16 | +import org.onosproject.segmentrouting.config.NetworkConfig.LinkConfig; | ||
17 | +import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig; | ||
18 | +import org.slf4j.Logger; | ||
19 | +import org.slf4j.LoggerFactory; | ||
20 | + | ||
21 | +import com.fasterxml.jackson.core.JsonParseException; | ||
22 | +import com.fasterxml.jackson.databind.JsonMappingException; | ||
23 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
24 | + | ||
25 | +/** | ||
26 | + * NetworkConfigManager manages all network configuration for switches, links | ||
27 | + * and any other state that needs to be configured for correct network | ||
28 | + * operation. | ||
29 | + * | ||
30 | + */ | ||
31 | +public class NetworkConfigManager implements NetworkConfigService { | ||
32 | + protected static final Logger log = LoggerFactory | ||
33 | + .getLogger(NetworkConfigManager.class); | ||
34 | + private static final String CONFIG_DIR = "../config"; | ||
35 | + private static final String DEFAULT_CONFIG_FILE = "segmentrouting.conf"; | ||
36 | + private final String configFileName = DEFAULT_CONFIG_FILE; | ||
37 | + /** | ||
38 | + * JSON Config file needs to use one of the following types for defining the | ||
39 | + * kind of switch or link it wishes to configure. | ||
40 | + */ | ||
41 | + public static final String SEGMENT_ROUTER = "Router_SR"; | ||
42 | + | ||
43 | + public static final String PKT_LINK = "pktLink"; | ||
44 | + | ||
45 | + NetworkConfig networkConfig; | ||
46 | + private ConcurrentMap<DeviceId, SwitchConfig> configuredSwitches; | ||
47 | + private ConcurrentMap<Link, LinkConfig> configuredLinks; | ||
48 | + private Map<String, DeviceId> nameToDpid; | ||
49 | + | ||
50 | + @Override | ||
51 | + public SwitchConfigStatus checkSwitchConfig(DeviceId dpid) { | ||
52 | + SwitchConfig swc = configuredSwitches.get(dpid); | ||
53 | + if (networkConfig.getRestrictSwitches()) { | ||
54 | + // default deny behavior | ||
55 | + if (swc == null) { | ||
56 | + // switch is not configured - we deny this switch | ||
57 | + return new SwitchConfigStatus(NetworkConfigState.DENY, null, | ||
58 | + "Switch not configured, in network denying switches by default."); | ||
59 | + } | ||
60 | + if (swc.isAllowed()) { | ||
61 | + // switch is allowed in config, return configured attributes | ||
62 | + return new SwitchConfigStatus(NetworkConfigState.ACCEPT_ADD, swc); | ||
63 | + } else { | ||
64 | + // switch has been configured off (administratively down) | ||
65 | + return new SwitchConfigStatus(NetworkConfigState.DENY, null, | ||
66 | + "Switch configured down (allowed=false)."); | ||
67 | + } | ||
68 | + } else { | ||
69 | + // default allow behavior | ||
70 | + if (swc == null) { | ||
71 | + // no config to add | ||
72 | + return new SwitchConfigStatus(NetworkConfigState.ACCEPT, null); | ||
73 | + } | ||
74 | + if (swc.isAllowed()) { | ||
75 | + // switch is allowed in config, return configured attributes | ||
76 | + return new SwitchConfigStatus(NetworkConfigState.ACCEPT_ADD, swc); | ||
77 | + } else { | ||
78 | + // switch has been configured off (administratively down) | ||
79 | + return new SwitchConfigStatus(NetworkConfigState.DENY, null, | ||
80 | + "Switch configured down (allowed=false)."); | ||
81 | + } | ||
82 | + } | ||
83 | + | ||
84 | + } | ||
85 | + | ||
86 | + @Override | ||
87 | + public LinkConfigStatus checkLinkConfig(Link linkTuple) { | ||
88 | + LinkConfig lkc = getConfiguredLink(linkTuple); | ||
89 | + // links are always disallowed if any one of the nodes that make up the | ||
90 | + // link are disallowed | ||
91 | + DeviceId linkNode1 = linkTuple.src().deviceId(); | ||
92 | + SwitchConfigStatus scs1 = checkSwitchConfig(linkNode1); | ||
93 | + if (scs1.getConfigState() == NetworkConfigState.DENY) { | ||
94 | + return new LinkConfigStatus(NetworkConfigState.DENY, null, | ||
95 | + "Link-node: " + linkNode1 + " denied by config: " + scs1.getMsg()); | ||
96 | + } | ||
97 | + DeviceId linkNode2 = linkTuple.dst().deviceId(); | ||
98 | + SwitchConfigStatus scs2 = checkSwitchConfig(linkNode2); | ||
99 | + if (scs2.getConfigState() == NetworkConfigState.DENY) { | ||
100 | + return new LinkConfigStatus(NetworkConfigState.DENY, null, | ||
101 | + "Link-node: " + linkNode2 + " denied by config: " + scs2.getMsg()); | ||
102 | + } | ||
103 | + if (networkConfig.getRestrictLinks()) { | ||
104 | + // default deny behavior | ||
105 | + if (lkc == null) { | ||
106 | + // link is not configured - we deny this link | ||
107 | + return new LinkConfigStatus(NetworkConfigState.DENY, null, | ||
108 | + "Link not configured, in network denying links by default."); | ||
109 | + } | ||
110 | + if (lkc.isAllowed()) { | ||
111 | + // link is allowed in config, return configured attributes | ||
112 | + return new LinkConfigStatus(NetworkConfigState.ACCEPT_ADD, lkc); | ||
113 | + } else { | ||
114 | + // link has been configured off (administratively down) | ||
115 | + return new LinkConfigStatus(NetworkConfigState.DENY, null, | ||
116 | + "Link configured down (allowed=false)."); | ||
117 | + } | ||
118 | + } else { | ||
119 | + // default allow behavior | ||
120 | + if (lkc == null) { | ||
121 | + // no config to add | ||
122 | + return new LinkConfigStatus(NetworkConfigState.ACCEPT, null); | ||
123 | + } | ||
124 | + if (lkc.isAllowed()) { | ||
125 | + // link is allowed in config, return configured attributes | ||
126 | + return new LinkConfigStatus(NetworkConfigState.ACCEPT_ADD, lkc); | ||
127 | + } else { | ||
128 | + // link has been configured off (administratively down) | ||
129 | + return new LinkConfigStatus(NetworkConfigState.DENY, null, | ||
130 | + "Link configured down (allowed=false)."); | ||
131 | + } | ||
132 | + } | ||
133 | + | ||
134 | + } | ||
135 | + | ||
136 | + @Override | ||
137 | + public List<SwitchConfig> getConfiguredAllowedSwitches() { | ||
138 | + List<SwitchConfig> allowed = new ArrayList<SwitchConfig>(); | ||
139 | + for (SwitchConfig swc : configuredSwitches.values()) { | ||
140 | + if (swc.isAllowed()) { | ||
141 | + allowed.add(swc); | ||
142 | + } | ||
143 | + } | ||
144 | + return allowed; | ||
145 | + } | ||
146 | + | ||
147 | + @Override | ||
148 | + public List<LinkConfig> getConfiguredAllowedLinks() { | ||
149 | + List<LinkConfig> allowed = new ArrayList<LinkConfig>(); | ||
150 | + for (LinkConfig lkc : configuredLinks.values()) { | ||
151 | + if (lkc.isAllowed()) { | ||
152 | + allowed.add(lkc); | ||
153 | + } | ||
154 | + } | ||
155 | + return allowed; | ||
156 | + } | ||
157 | + | ||
158 | + @Override | ||
159 | + public DeviceId getDpidForName(String name) { | ||
160 | + if (nameToDpid.get(name) != null) { | ||
161 | + return nameToDpid.get(name); | ||
162 | + } | ||
163 | + return null; | ||
164 | + } | ||
165 | + | ||
166 | + // ************** | ||
167 | + // Private methods | ||
168 | + // ************** | ||
169 | + | ||
170 | + private void loadNetworkConfig() { | ||
171 | + File configFile = new File(CONFIG_DIR, configFileName); | ||
172 | + ObjectMapper mapper = new ObjectMapper(); | ||
173 | + networkConfig = new NetworkConfig(); | ||
174 | + | ||
175 | + try { | ||
176 | + networkConfig = mapper.readValue(configFile, | ||
177 | + NetworkConfig.class); | ||
178 | + } catch (JsonParseException e) { | ||
179 | + String err = String.format("JsonParseException while loading network " | ||
180 | + + "config from file: %s: %s", configFileName, | ||
181 | + e.getMessage()); | ||
182 | + throw new NetworkConfigException.ErrorConfig(err); | ||
183 | + } catch (JsonMappingException e) { | ||
184 | + String err = String.format( | ||
185 | + "JsonMappingException while loading network config " | ||
186 | + + "from file: %s: %s", | ||
187 | + configFileName, | ||
188 | + e.getMessage()); | ||
189 | + throw new NetworkConfigException.ErrorConfig(err); | ||
190 | + } catch (IOException e) { | ||
191 | + String err = String.format("IOException while loading network config " | ||
192 | + + "from file: %s %s", configFileName, e.getMessage()); | ||
193 | + throw new NetworkConfigException.ErrorConfig(err); | ||
194 | + } | ||
195 | + | ||
196 | + log.info("Network config specifies: {} switches and {} links", | ||
197 | + (networkConfig.getRestrictSwitches()) | ||
198 | + ? networkConfig.getSwitchConfig().size() : "default allow", | ||
199 | + (networkConfig.getRestrictLinks()) | ||
200 | + ? networkConfig.getLinkConfig().size() : "default allow"); | ||
201 | + } | ||
202 | + | ||
203 | + private void parseNetworkConfig() { | ||
204 | + List<SwitchConfig> swConfList = networkConfig.getSwitchConfig(); | ||
205 | + List<LinkConfig> lkConfList = networkConfig.getLinkConfig(); | ||
206 | + validateSwitchConfig(swConfList); | ||
207 | + createTypeSpecificSwitchConfig(swConfList); | ||
208 | + validateLinkConfig(lkConfList); | ||
209 | + createTypeSpecificLinkConfig(lkConfList); | ||
210 | + // TODO validate reachability matrix 'names' for configured dpids | ||
211 | + } | ||
212 | + | ||
213 | + private void createTypeSpecificSwitchConfig(List<SwitchConfig> swConfList) { | ||
214 | + for (SwitchConfig swc : swConfList) { | ||
215 | + nameToDpid.put(swc.getName(), swc.getDpid()); | ||
216 | + String swtype = swc.getType(); | ||
217 | + switch (swtype) { | ||
218 | + case SEGMENT_ROUTER: | ||
219 | + SwitchConfig sr = new SegmentRouterConfig(swc); | ||
220 | + configuredSwitches.put(sr.getDpid(), sr); | ||
221 | + break; | ||
222 | + default: | ||
223 | + throw new NetworkConfigException.UnknownSwitchType(swtype, | ||
224 | + swc.getName()); | ||
225 | + } | ||
226 | + } | ||
227 | + } | ||
228 | + | ||
229 | + private void createTypeSpecificLinkConfig(List<LinkConfig> lkConfList) { | ||
230 | + for (LinkConfig lkc : lkConfList) { | ||
231 | + String lktype = lkc.getType(); | ||
232 | + switch (lktype) { | ||
233 | + case PKT_LINK: | ||
234 | + PktLinkConfig pk = new PktLinkConfig(lkc); | ||
235 | + for (Link lt : pk.getLinkTupleList()) { | ||
236 | + configuredLinks.put(lt, pk); | ||
237 | + } | ||
238 | + break; | ||
239 | + default: | ||
240 | + throw new NetworkConfigException.UnknownLinkType(lktype, | ||
241 | + lkc.getNodeDpid1(), lkc.getNodeDpid2()); | ||
242 | + } | ||
243 | + } | ||
244 | + } | ||
245 | + | ||
246 | + private void validateSwitchConfig(List<SwitchConfig> swConfList) { | ||
247 | + Set<DeviceId> swDpids = new HashSet<DeviceId>(); | ||
248 | + Set<String> swNames = new HashSet<String>(); | ||
249 | + for (SwitchConfig swc : swConfList) { | ||
250 | + if (swc.getNodeDpid() == null || swc.getDpid() == null) { | ||
251 | + throw new NetworkConfigException.DpidNotSpecified(swc.getName()); | ||
252 | + } | ||
253 | + // ensure both String and DeviceId values of dpid are set | ||
254 | + if (!swc.getDpid().equals(DeviceId.deviceId(swc.getNodeDpid()))) { | ||
255 | + throw new NetworkConfigException.SwitchDpidNotConverted( | ||
256 | + swc.getName()); | ||
257 | + } | ||
258 | + if (swc.getName() == null) { | ||
259 | + throw new NetworkConfigException.NameNotSpecified(swc.getDpid()); | ||
260 | + } | ||
261 | + if (swc.getType() == null) { | ||
262 | + throw new NetworkConfigException.SwitchTypeNotSpecified( | ||
263 | + swc.getDpid()); | ||
264 | + } | ||
265 | + if (!swDpids.add(swc.getDpid())) { | ||
266 | + throw new NetworkConfigException.DuplicateDpid(swc.getDpid()); | ||
267 | + } | ||
268 | + if (!swNames.add(swc.getName())) { | ||
269 | + throw new NetworkConfigException.DuplicateName(swc.getName()); | ||
270 | + } | ||
271 | + // TODO Add more validations | ||
272 | + } | ||
273 | + } | ||
274 | + | ||
275 | + private void validateLinkConfig(List<LinkConfig> lkConfList) { | ||
276 | + for (LinkConfig lkc : lkConfList) { | ||
277 | + if (lkc.getNodeDpid1() == null || lkc.getNodeDpid2() == null) { | ||
278 | + throw new NetworkConfigException.LinkDpidNotSpecified( | ||
279 | + lkc.getNodeDpid1(), lkc.getNodeDpid2()); | ||
280 | + } | ||
281 | + // ensure both String and Long values are set | ||
282 | + if (!lkc.getDpid1().equals(DeviceId.deviceId(lkc.getNodeDpid1())) || | ||
283 | + !lkc.getDpid2().equals(DeviceId.deviceId(lkc.getNodeDpid2()))) { | ||
284 | + throw new NetworkConfigException.LinkDpidNotConverted( | ||
285 | + lkc.getNodeDpid1(), lkc.getNodeDpid2()); | ||
286 | + } | ||
287 | + if (lkc.getType() == null) { | ||
288 | + throw new NetworkConfigException.LinkTypeNotSpecified( | ||
289 | + lkc.getNodeDpid1(), lkc.getNodeDpid2()); | ||
290 | + } | ||
291 | + if (configuredSwitches.get(lkc.getDpid1()) == null) { | ||
292 | + throw new NetworkConfigException.LinkForUnknownSwitchConfig( | ||
293 | + lkc.getNodeDpid1()); | ||
294 | + } | ||
295 | + if (configuredSwitches.get(lkc.getDpid2()) == null) { | ||
296 | + throw new NetworkConfigException.LinkForUnknownSwitchConfig( | ||
297 | + lkc.getNodeDpid2()); | ||
298 | + } | ||
299 | + // TODO add more validations | ||
300 | + } | ||
301 | + | ||
302 | + } | ||
303 | + | ||
304 | + private LinkConfig getConfiguredLink(Link linkTuple) { | ||
305 | + LinkConfig lkc = null; | ||
306 | + // first try the unidirectional link with the ports assigned | ||
307 | + lkc = configuredLinks.get(linkTuple); | ||
308 | + return lkc; | ||
309 | + } | ||
310 | + | ||
311 | + | ||
312 | + /** | ||
313 | + * Initializes the network configuration manager module by | ||
314 | + * loading and parsing the network configuration file. | ||
315 | + */ | ||
316 | + public void init() { | ||
317 | + loadNetworkConfig(); | ||
318 | + configuredSwitches = new ConcurrentHashMap<DeviceId, SwitchConfig>(); | ||
319 | + configuredLinks = new ConcurrentHashMap<Link, LinkConfig>(); | ||
320 | + nameToDpid = new HashMap<String, DeviceId>(); | ||
321 | + parseNetworkConfig(); | ||
322 | + } | ||
323 | +} |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/NetworkConfigService.java
0 → 100644
1 | +package org.onosproject.segmentrouting.config; | ||
2 | + | ||
3 | +import java.util.List; | ||
4 | + | ||
5 | +import org.onosproject.net.DeviceId; | ||
6 | +import org.onosproject.net.Link; | ||
7 | +import org.onosproject.segmentrouting.config.NetworkConfig.LinkConfig; | ||
8 | +import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig; | ||
9 | + | ||
10 | +/** | ||
11 | + * Exposes methods to retrieve network configuration. | ||
12 | + * | ||
13 | + * TODO: currently only startup-configuration is exposed and such configuration | ||
14 | + * cannot be changed at runtime. Need to add runtime support for changes to | ||
15 | + * configuration (via REST/CLI) in future releases. | ||
16 | + * | ||
17 | + * TODO: return immutable objects or defensive copies of network config so that | ||
18 | + * users of this API do not inadvertently or maliciously change network config. | ||
19 | + */ | ||
20 | +public interface NetworkConfigService { | ||
21 | + | ||
22 | + /** | ||
23 | + * Suggests the action to be taken by the caller given the configuration | ||
24 | + * associated with the queried network-object (eg. switch, link etc.). | ||
25 | + */ | ||
26 | + public enum NetworkConfigState { | ||
27 | + /** | ||
28 | + * Associated network object has been configured to not be allowed in | ||
29 | + * the network. | ||
30 | + */ | ||
31 | + DENY, | ||
32 | + | ||
33 | + /** | ||
34 | + * Associated network object has been configured to be allowed in the | ||
35 | + * network. | ||
36 | + */ | ||
37 | + ACCEPT, | ||
38 | + | ||
39 | + /** | ||
40 | + * Associated network object has been configured to be allowed in the | ||
41 | + * network. In addition, there are configured parameters that should be | ||
42 | + * added to the object. | ||
43 | + */ | ||
44 | + ACCEPT_ADD, | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Returns the configuration outcome (accept, deny etc.), and any configured | ||
49 | + * parameters to the caller, in response to a query for the configuration | ||
50 | + * associated with a switch. | ||
51 | + */ | ||
52 | + public class SwitchConfigStatus { | ||
53 | + private NetworkConfigState configState; | ||
54 | + private SwitchConfig switchConfig; | ||
55 | + private String msg; | ||
56 | + | ||
57 | + SwitchConfigStatus(NetworkConfigState configState, | ||
58 | + SwitchConfig switchConfig, String msg) { | ||
59 | + this.configState = configState; | ||
60 | + this.switchConfig = switchConfig; | ||
61 | + this.msg = msg; | ||
62 | + } | ||
63 | + | ||
64 | + SwitchConfigStatus(NetworkConfigState configState, | ||
65 | + SwitchConfig switchConfig) { | ||
66 | + this.configState = configState; | ||
67 | + this.switchConfig = switchConfig; | ||
68 | + this.msg = ""; | ||
69 | + } | ||
70 | + | ||
71 | + /** | ||
72 | + * Returns the configuration state for the switch. | ||
73 | + * | ||
74 | + * @return non-null NetworkConfigState | ||
75 | + */ | ||
76 | + public NetworkConfigState getConfigState() { | ||
77 | + return configState; | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * Returns the switch configuration, which may be null if no | ||
82 | + * configuration exists, or if the configuration state disallows the | ||
83 | + * switch. | ||
84 | + * | ||
85 | + * @return SwitchConfig, the switch configuration, or null | ||
86 | + */ | ||
87 | + public SwitchConfig getSwitchConfig() { | ||
88 | + return switchConfig; | ||
89 | + } | ||
90 | + | ||
91 | + /** | ||
92 | + * User readable string typically used to specify the reason why a | ||
93 | + * switch is being disallowed. | ||
94 | + * | ||
95 | + * @return A non-null but possibly empty String | ||
96 | + */ | ||
97 | + public String getMsg() { | ||
98 | + return msg; | ||
99 | + } | ||
100 | + | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * Reserved for future use. | ||
105 | + * | ||
106 | + * Returns the configuration outcome (accept, deny etc.), and any configured | ||
107 | + * parameters to the caller, in response to a query for the configuration | ||
108 | + * associated with a link. | ||
109 | + */ | ||
110 | + public class LinkConfigStatus { | ||
111 | + private NetworkConfigState configState; | ||
112 | + private LinkConfig linkConfig; | ||
113 | + private String msg; | ||
114 | + | ||
115 | + LinkConfigStatus(NetworkConfigState configState, | ||
116 | + LinkConfig linkConfig, String msg) { | ||
117 | + this.configState = configState; | ||
118 | + this.linkConfig = linkConfig; | ||
119 | + this.msg = msg; | ||
120 | + } | ||
121 | + | ||
122 | + LinkConfigStatus(NetworkConfigState configState, | ||
123 | + LinkConfig linkConfig) { | ||
124 | + this.configState = configState; | ||
125 | + this.linkConfig = linkConfig; | ||
126 | + this.msg = ""; | ||
127 | + } | ||
128 | + | ||
129 | + /** | ||
130 | + * Returns the configuration state for the link. | ||
131 | + * | ||
132 | + * @return non-null NetworkConfigState | ||
133 | + */ | ||
134 | + public NetworkConfigState getConfigState() { | ||
135 | + return configState; | ||
136 | + } | ||
137 | + | ||
138 | + /** | ||
139 | + * Returns the link configuration, which may be null if no configuration | ||
140 | + * exists, or if the configuration state disallows the link. | ||
141 | + * | ||
142 | + * @return SwitchConfig, the switch configuration, or null | ||
143 | + */ | ||
144 | + public LinkConfig getLinkConfig() { | ||
145 | + return linkConfig; | ||
146 | + } | ||
147 | + | ||
148 | + /** | ||
149 | + * User readable string typically used to specify the reason why a link | ||
150 | + * is being disallowed. | ||
151 | + * | ||
152 | + * @return msg A non-null but possibly empty String | ||
153 | + */ | ||
154 | + public String getMsg() { | ||
155 | + return msg; | ||
156 | + } | ||
157 | + | ||
158 | + } | ||
159 | + | ||
160 | + /** | ||
161 | + * Checks the switch configuration (if any) associated with the 'dpid'. | ||
162 | + * Determines if the switch should be allowed or denied according to | ||
163 | + * configuration rules. | ||
164 | + * | ||
165 | + * The method always returns a non-null SwitchConfigStatus. The enclosed | ||
166 | + * ConfigState contains the result of the check. The enclosed SwitchConfig | ||
167 | + * may or may not be null, depending on the outcome of the check. | ||
168 | + * | ||
169 | + * @param dpid device id of the switch to be queried | ||
170 | + * @return SwitchConfigStatus with outcome of check and associated config. | ||
171 | + */ | ||
172 | + public SwitchConfigStatus checkSwitchConfig(DeviceId dpid); | ||
173 | + | ||
174 | + /** | ||
175 | + * Reserved for future use. | ||
176 | + * | ||
177 | + * Checks the link configuration (if any) associated with the 'link'. | ||
178 | + * Determines if the link should be allowed or denied according to | ||
179 | + * configuration rules. Note that the 'link' is a unidirectional link which | ||
180 | + * checked against configuration that is typically defined for a | ||
181 | + * bidirectional link. The caller may make a second call if it wishes to | ||
182 | + * check the 'reverse' direction. | ||
183 | + * | ||
184 | + * Also note that the configuration may not specify ports for a given | ||
185 | + * bidirectional link. In such cases, the configuration applies to all links | ||
186 | + * between the two switches. This method will check the given 'link' against | ||
187 | + * such configuration. | ||
188 | + | ||
189 | + * The method always returns a non-null LinkConfigStatus. The enclosed | ||
190 | + * ConfigState contains the result of the check. The enclosed LinkConfig may | ||
191 | + * or may not be null, depending on the outcome of the check. | ||
192 | + * | ||
193 | + * @param linkTuple unidirectional link to be queried | ||
194 | + * @return LinkConfigStatus with outcome of check and associated config. | ||
195 | + */ | ||
196 | + public LinkConfigStatus checkLinkConfig(Link linkTuple); | ||
197 | + | ||
198 | + /** | ||
199 | + * Retrieves a list of switches that have been configured, and have been | ||
200 | + * determined to be 'allowed' in the network, according to configuration | ||
201 | + * rules. | ||
202 | + * | ||
203 | + * Note that it is possible that there are other switches that are allowed | ||
204 | + * in the network that have NOT been configured. Such switches will not be a | ||
205 | + * part of the returned list. | ||
206 | + * | ||
207 | + * Also note that it is possible that some switches will not be discovered | ||
208 | + * and the only way the controller can know about these switches is via | ||
209 | + * configuration. Such switches will be included in this list. It is up to | ||
210 | + * the caller to determine which SwitchConfig applies to non-discovered | ||
211 | + * switches. | ||
212 | + * | ||
213 | + * @return a non-null List of SwitchConfig which may be empty | ||
214 | + */ | ||
215 | + public List<SwitchConfig> getConfiguredAllowedSwitches(); | ||
216 | + | ||
217 | + /** | ||
218 | + * Reserved for future use. | ||
219 | + * | ||
220 | + * Retrieves a list of links that have been configured, and have been | ||
221 | + * determined to be 'allowed' in the network, according to configuration | ||
222 | + * rules. | ||
223 | + * | ||
224 | + * Note that it is possible that there are other links that are allowed in | ||
225 | + * the network that have NOT been configured. Such links will not be a part | ||
226 | + * of the returned list. | ||
227 | + * | ||
228 | + * Also note that it is possible that some links will not be discovered and | ||
229 | + * the only way the controller can know about these links is via | ||
230 | + * configuration. Such links will be included in this list. It is up to the | ||
231 | + * caller to determine which LinkConfig applies to non-discovered links. | ||
232 | + * | ||
233 | + * In addition, note that the LinkConfig applies to the configured | ||
234 | + * bi-directional link, which may or may not have declared ports. The | ||
235 | + * associated unidirectional LinkTuple can be retrieved from the | ||
236 | + * getLinkTupleList() method in the LinkConfig object. | ||
237 | + * | ||
238 | + * @return a non-null List of LinkConfig which may be empty | ||
239 | + */ | ||
240 | + public List<LinkConfig> getConfiguredAllowedLinks(); | ||
241 | + | ||
242 | + /** | ||
243 | + * Retrieves the Dpid associated with a 'name' for a configured switch | ||
244 | + * object. This method does not check of the switches are 'allowed' by | ||
245 | + * config. | ||
246 | + * | ||
247 | + * @param name device name | ||
248 | + * @return the Dpid corresponding to a given 'name', or null if no | ||
249 | + * configured switch was found for the given 'name'. | ||
250 | + */ | ||
251 | + public DeviceId getDpidForName(String name); | ||
252 | + | ||
253 | +} |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PktLinkConfig.java
0 → 100644
1 | +package org.onosproject.segmentrouting.config; | ||
2 | + | ||
3 | +import java.util.List; | ||
4 | +import java.util.Map.Entry; | ||
5 | +import java.util.Set; | ||
6 | +import java.util.concurrent.ConcurrentHashMap; | ||
7 | + | ||
8 | +import org.onosproject.net.Link; | ||
9 | +import org.onosproject.segmentrouting.config.NetworkConfig.LinkConfig; | ||
10 | +import org.slf4j.Logger; | ||
11 | +import org.slf4j.LoggerFactory; | ||
12 | + | ||
13 | +import com.fasterxml.jackson.databind.JsonNode; | ||
14 | + | ||
15 | +/** | ||
16 | + * Reserved for future use. | ||
17 | + * Configuration for a link between two packet-switches. | ||
18 | + */ | ||
19 | +public class PktLinkConfig extends LinkConfig { | ||
20 | + protected static final Logger log = LoggerFactory | ||
21 | + .getLogger(PktLinkConfig.class); | ||
22 | + private int port1; | ||
23 | + private int port2; | ||
24 | + private String nodeName1; | ||
25 | + private String nodeName2; | ||
26 | + private List<Link> linkTupleList; | ||
27 | + | ||
28 | + public PktLinkConfig(LinkConfig lkc) { | ||
29 | + nodeDpid1 = lkc.getNodeDpid1(); | ||
30 | + nodeDpid2 = lkc.getNodeDpid2(); | ||
31 | + dpid1 = lkc.getDpid1(); | ||
32 | + dpid2 = lkc.getDpid2(); | ||
33 | + type = lkc.getType(); | ||
34 | + allowed = lkc.isAllowed(); | ||
35 | + params = lkc.getParams(); | ||
36 | + publishAttributes = new ConcurrentHashMap<String, String>(); | ||
37 | + parseParams(); | ||
38 | + validateParams(); | ||
39 | + setPublishAttributes(); | ||
40 | + } | ||
41 | + | ||
42 | + // ******************** | ||
43 | + // Packet Link Configuration | ||
44 | + // ******************** | ||
45 | + | ||
46 | + public int getPort1() { | ||
47 | + return port1; | ||
48 | + } | ||
49 | + | ||
50 | + public void setPort1(int port1) { | ||
51 | + this.port1 = port1; | ||
52 | + } | ||
53 | + | ||
54 | + public int getPort2() { | ||
55 | + return port2; | ||
56 | + } | ||
57 | + | ||
58 | + public void setPort2(int port2) { | ||
59 | + this.port2 = port2; | ||
60 | + } | ||
61 | + | ||
62 | + public String getNodeName1() { | ||
63 | + return nodeName1; | ||
64 | + } | ||
65 | + | ||
66 | + public void setNodeName1(String nodeName1) { | ||
67 | + this.nodeName1 = nodeName1; | ||
68 | + } | ||
69 | + | ||
70 | + public String getNodeName2() { | ||
71 | + return nodeName2; | ||
72 | + } | ||
73 | + | ||
74 | + public void setNodeName2(String nodeName2) { | ||
75 | + this.nodeName2 = nodeName2; | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * Returns the two unidirectional links corresponding to the packet-link | ||
80 | + * configuration. It is possible that the ports in the LinkTuple have | ||
81 | + * portnumber '0', implying that the configuration applies to all links | ||
82 | + * between the two switches. | ||
83 | + * | ||
84 | + * @return a list of LinkTuple with exactly 2 unidirectional links | ||
85 | + */ | ||
86 | + public List<Link> getLinkTupleList() { | ||
87 | + return linkTupleList; | ||
88 | + } | ||
89 | + | ||
90 | + private void setPublishAttributes() { | ||
91 | + | ||
92 | + } | ||
93 | + | ||
94 | + private void parseParams() { | ||
95 | + if (params == null) { | ||
96 | + throw new PktLinkParamsNotSpecified(nodeDpid1, nodeDpid2); | ||
97 | + } | ||
98 | + Set<Entry<String, JsonNode>> m = params.entrySet(); | ||
99 | + for (Entry<String, JsonNode> e : m) { | ||
100 | + String key = e.getKey(); | ||
101 | + JsonNode j = e.getValue(); | ||
102 | + if (key.equals("nodeName1")) { | ||
103 | + setNodeName1(j.asText()); | ||
104 | + } else if (key.equals("nodeName2")) { | ||
105 | + setNodeName2(j.asText()); | ||
106 | + } else if (key.equals("port1")) { | ||
107 | + setPort1(j.asInt()); | ||
108 | + } else if (key.equals("port2")) { | ||
109 | + setPort2(j.asInt()); | ||
110 | + } else { | ||
111 | + throw new UnknownPktLinkConfig(key, nodeDpid1, nodeDpid2); | ||
112 | + } | ||
113 | + } | ||
114 | + } | ||
115 | + | ||
116 | + private void validateParams() { | ||
117 | + // TODO - wrong-names, duplicate links, | ||
118 | + // duplicate use of port, is switch-allowed for which link is allowed? | ||
119 | + // valid port numbers | ||
120 | + } | ||
121 | + | ||
122 | + public static class PktLinkParamsNotSpecified extends RuntimeException { | ||
123 | + private static final long serialVersionUID = 6247582323691265513L; | ||
124 | + | ||
125 | + public PktLinkParamsNotSpecified(String dpidA, String dpidB) { | ||
126 | + super(); | ||
127 | + log.error("Params required for packet link - not specified " | ||
128 | + + "for link between switch1:{} and switch2:{}", | ||
129 | + dpidA, dpidB); | ||
130 | + } | ||
131 | + } | ||
132 | + | ||
133 | + public static class UnknownPktLinkConfig extends RuntimeException { | ||
134 | + private static final long serialVersionUID = -5750132094884129179L; | ||
135 | + | ||
136 | + public UnknownPktLinkConfig(String key, String dpidA, String dpidB) { | ||
137 | + super(); | ||
138 | + log.error("Unknown packet-link config {} for link between" | ||
139 | + + " dpid1: {} and dpid2: {}", key, | ||
140 | + dpidA, dpidB); | ||
141 | + } | ||
142 | + } | ||
143 | + | ||
144 | +} |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRouterConfig.java
0 → 100644
1 | +package org.onosproject.segmentrouting.config; | ||
2 | + | ||
3 | +import java.io.IOException; | ||
4 | +import java.util.ArrayList; | ||
5 | +import java.util.Iterator; | ||
6 | +import java.util.List; | ||
7 | +import java.util.Map.Entry; | ||
8 | +import java.util.Set; | ||
9 | +import java.util.concurrent.ConcurrentHashMap; | ||
10 | + | ||
11 | +import org.onosproject.net.DeviceId; | ||
12 | +import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig; | ||
13 | +import org.slf4j.Logger; | ||
14 | +import org.slf4j.LoggerFactory; | ||
15 | + | ||
16 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
17 | +import com.fasterxml.jackson.databind.JsonNode; | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | + | ||
20 | +/** | ||
21 | + * Manages additional configuration for switches configured as Segment Routers. | ||
22 | + */ | ||
23 | +public class SegmentRouterConfig extends SwitchConfig { | ||
24 | + protected static final Logger log = LoggerFactory | ||
25 | + .getLogger(SegmentRouterConfig.class); | ||
26 | + private String routerIp; | ||
27 | + private String routerMac; | ||
28 | + private int nodeSid; | ||
29 | + private boolean isEdgeRouter; | ||
30 | + private List<AdjacencySid> adjacencySids; | ||
31 | + private List<Subnet> subnets; | ||
32 | + | ||
33 | + public static final String ROUTER_IP = "routerIp"; | ||
34 | + public static final String ROUTER_MAC = "routerMac"; | ||
35 | + public static final String NODE_SID = "nodeSid"; | ||
36 | + public static final String ADJACENCY_SIDS = "adjacencySids"; | ||
37 | + public static final String SUBNETS = "subnets"; | ||
38 | + public static final String ISEDGE = "isEdgeRouter"; | ||
39 | + private static final int SRGB_MAX = 1000; | ||
40 | + | ||
41 | + /** | ||
42 | + * Parses and validates the additional configuration parameters applicable | ||
43 | + * to segment routers. | ||
44 | + * | ||
45 | + * @param swc switch configuration | ||
46 | + */ | ||
47 | + public SegmentRouterConfig(SwitchConfig swc) { | ||
48 | + this.setName(swc.getName()); | ||
49 | + this.setDpid(swc.getDpid()); | ||
50 | + this.setType(swc.getType()); | ||
51 | + this.setLatitude(swc.getLatitude()); | ||
52 | + this.setLongitude(swc.getLongitude()); | ||
53 | + this.setParams(swc.getParams()); | ||
54 | + this.setAllowed(swc.isAllowed()); | ||
55 | + publishAttributes = new ConcurrentHashMap<String, String>(); | ||
56 | + adjacencySids = new ArrayList<AdjacencySid>(); | ||
57 | + subnets = new ArrayList<Subnet>(); | ||
58 | + parseParams(); | ||
59 | + validateParams(); | ||
60 | + setPublishAttributes(); | ||
61 | + } | ||
62 | + | ||
63 | + /** | ||
64 | + * Returns the configured segment router IP address. | ||
65 | + * | ||
66 | + * @return ip address in string format | ||
67 | + */ | ||
68 | + public String getRouterIp() { | ||
69 | + return routerIp; | ||
70 | + } | ||
71 | + | ||
72 | + public void setRouterIp(String routerIp) { | ||
73 | + this.routerIp = routerIp; | ||
74 | + } | ||
75 | + | ||
76 | + /** | ||
77 | + * Returns the configured segment router mac address. | ||
78 | + * | ||
79 | + * @return mac address in string format | ||
80 | + */ | ||
81 | + public String getRouterMac() { | ||
82 | + return routerMac; | ||
83 | + } | ||
84 | + | ||
85 | + public void setRouterMac(String routerMac) { | ||
86 | + this.routerMac = routerMac; | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * Returns the configured sID for a segment router. | ||
91 | + * | ||
92 | + * @return segment identifier | ||
93 | + */ | ||
94 | + public int getNodeSid() { | ||
95 | + return nodeSid; | ||
96 | + } | ||
97 | + | ||
98 | + public void setNodeSid(int nodeSid) { | ||
99 | + this.nodeSid = nodeSid; | ||
100 | + } | ||
101 | + | ||
102 | + /** | ||
103 | + * Returns the flag that indicates the configured segment router | ||
104 | + * is edge or backbone router. | ||
105 | + * | ||
106 | + * @return boolean | ||
107 | + */ | ||
108 | + public boolean isEdgeRouter() { | ||
109 | + return isEdgeRouter; | ||
110 | + } | ||
111 | + | ||
112 | + public void setIsEdgeRouter(boolean isEdge) { | ||
113 | + this.isEdgeRouter = isEdge; | ||
114 | + } | ||
115 | + | ||
116 | + /** | ||
117 | + * Class representing segment router adjacency identifier. | ||
118 | + */ | ||
119 | + public static class AdjacencySid { | ||
120 | + private int adjSid; | ||
121 | + private List<Integer> ports; | ||
122 | + | ||
123 | + public AdjacencySid(int adjSid, List<Integer> ports) { | ||
124 | + this.ports = ports; | ||
125 | + this.adjSid = adjSid; | ||
126 | + } | ||
127 | + | ||
128 | + /** | ||
129 | + * Returns the list of ports part of a segment | ||
130 | + * router adjacency identifier. | ||
131 | + * | ||
132 | + * @return list of integers | ||
133 | + */ | ||
134 | + public List<Integer> getPorts() { | ||
135 | + return ports; | ||
136 | + } | ||
137 | + | ||
138 | + public void setPorts(List<Integer> ports) { | ||
139 | + this.ports = ports; | ||
140 | + } | ||
141 | + | ||
142 | + /** | ||
143 | + * Returns the configured adjacency id of a segment router. | ||
144 | + * | ||
145 | + * @return integer | ||
146 | + */ | ||
147 | + public int getAdjSid() { | ||
148 | + return adjSid; | ||
149 | + } | ||
150 | + | ||
151 | + public void setAdjSid(int adjSid) { | ||
152 | + this.adjSid = adjSid; | ||
153 | + } | ||
154 | + } | ||
155 | + | ||
156 | + /** | ||
157 | + * Returns the configured adjacent segment IDs for a segment router. | ||
158 | + * | ||
159 | + * @return list of adjacency identifier | ||
160 | + */ | ||
161 | + public List<AdjacencySid> getAdjacencySids() { | ||
162 | + return adjacencySids; | ||
163 | + } | ||
164 | + | ||
165 | + public void setAdjacencySids(List<AdjacencySid> adjacencySids) { | ||
166 | + this.adjacencySids = adjacencySids; | ||
167 | + } | ||
168 | + | ||
169 | + /** | ||
170 | + * Class representing a subnet attached to a segment router. | ||
171 | + */ | ||
172 | + public static class Subnet { | ||
173 | + private int portNo; | ||
174 | + private String subnetIp; | ||
175 | + | ||
176 | + public Subnet(int portNo, String subnetIp) { | ||
177 | + this.portNo = portNo; | ||
178 | + this.subnetIp = subnetIp; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Returns the port number of segment router on | ||
183 | + * which subnet is attached. | ||
184 | + * | ||
185 | + * @return integer | ||
186 | + */ | ||
187 | + public int getPortNo() { | ||
188 | + return portNo; | ||
189 | + } | ||
190 | + | ||
191 | + public void setPortNo(int portNo) { | ||
192 | + this.portNo = portNo; | ||
193 | + } | ||
194 | + | ||
195 | + /** | ||
196 | + * Returns the configured subnet address. | ||
197 | + * | ||
198 | + * @return subnet ip address in string format | ||
199 | + */ | ||
200 | + public String getSubnetIp() { | ||
201 | + return subnetIp; | ||
202 | + } | ||
203 | + | ||
204 | + public void setSubnetIp(String subnetIp) { | ||
205 | + this.subnetIp = subnetIp; | ||
206 | + } | ||
207 | + } | ||
208 | + | ||
209 | + /** | ||
210 | + * Returns the configured subnets for a segment router. | ||
211 | + * | ||
212 | + * @return list of subnets | ||
213 | + */ | ||
214 | + public List<Subnet> getSubnets() { | ||
215 | + return subnets; | ||
216 | + } | ||
217 | + | ||
218 | + public void setSubnets(List<Subnet> subnets) { | ||
219 | + this.subnets = subnets; | ||
220 | + } | ||
221 | + | ||
222 | + // ******************** | ||
223 | + // Helper methods | ||
224 | + // ******************** | ||
225 | + | ||
226 | + private void parseParams() { | ||
227 | + if (params == null) { | ||
228 | + throw new NetworkConfigException.ParamsNotSpecified(name); | ||
229 | + } | ||
230 | + | ||
231 | + Set<Entry<String, JsonNode>> m = params.entrySet(); | ||
232 | + for (Entry<String, JsonNode> e : m) { | ||
233 | + String key = e.getKey(); | ||
234 | + JsonNode j = e.getValue(); | ||
235 | + if (key.equals("routerIp")) { | ||
236 | + setRouterIp(j.asText()); | ||
237 | + } else if (key.equals("routerMac")) { | ||
238 | + setRouterMac(j.asText()); | ||
239 | + } else if (key.equals("nodeSid")) { | ||
240 | + setNodeSid(j.asInt()); | ||
241 | + } else if (key.equals("isEdgeRouter")) { | ||
242 | + setIsEdgeRouter(j.asBoolean()); | ||
243 | + } else if (key.equals("adjacencySids") || key.equals("subnets")) { | ||
244 | + getInnerParams(j, key); | ||
245 | + } else { | ||
246 | + throw new UnknownSegmentRouterConfig(key, dpid); | ||
247 | + } | ||
248 | + } | ||
249 | + } | ||
250 | + | ||
251 | + private void getInnerParams(JsonNode j, String innerParam) { | ||
252 | + Iterator<JsonNode> innerList = j.elements(); | ||
253 | + while (innerList.hasNext()) { | ||
254 | + Iterator<Entry<String, JsonNode>> f = innerList.next().fields(); | ||
255 | + int portNo = -1; | ||
256 | + int adjSid = -1; | ||
257 | + String subnetIp = null; | ||
258 | + List<Integer> ports = null; | ||
259 | + while (f.hasNext()) { | ||
260 | + Entry<String, JsonNode> fe = f.next(); | ||
261 | + if (fe.getKey().equals("portNo")) { | ||
262 | + portNo = fe.getValue().asInt(); | ||
263 | + } else if (fe.getKey().equals("adjSid")) { | ||
264 | + adjSid = fe.getValue().asInt(); | ||
265 | + } else if (fe.getKey().equals("subnetIp")) { | ||
266 | + subnetIp = fe.getValue().asText(); | ||
267 | + } else if (fe.getKey().equals("ports")) { | ||
268 | + if (fe.getValue().isArray()) { | ||
269 | + Iterator<JsonNode> i = fe.getValue().elements(); | ||
270 | + ports = new ArrayList<Integer>(); | ||
271 | + while (i.hasNext()) { | ||
272 | + ports.add(i.next().asInt()); | ||
273 | + } | ||
274 | + } | ||
275 | + } else { | ||
276 | + throw new UnknownSegmentRouterConfig(fe.getKey(), dpid); | ||
277 | + } | ||
278 | + } | ||
279 | + if (innerParam.equals("adjacencySids")) { | ||
280 | + AdjacencySid ads = new AdjacencySid(adjSid, ports); | ||
281 | + adjacencySids.add(ads); | ||
282 | + } else { | ||
283 | + Subnet sip = new Subnet(portNo, subnetIp); | ||
284 | + subnets.add(sip); | ||
285 | + } | ||
286 | + } | ||
287 | + } | ||
288 | + | ||
289 | + private void validateParams() { | ||
290 | + if (routerIp == null) { | ||
291 | + throw new IpNotSpecified(dpid); | ||
292 | + } | ||
293 | + if (routerMac == null) { | ||
294 | + throw new MacNotSpecified(dpid); | ||
295 | + } | ||
296 | + if (isEdgeRouter && subnets.isEmpty()) { | ||
297 | + throw new SubnetNotSpecifiedInEdgeRouter(dpid); | ||
298 | + } | ||
299 | + if (!isEdgeRouter && !subnets.isEmpty()) { | ||
300 | + throw new SubnetSpecifiedInBackboneRouter(dpid); | ||
301 | + } | ||
302 | + if (nodeSid > SRGB_MAX) { | ||
303 | + throw new NodeLabelNotInSRGB(nodeSid, dpid); | ||
304 | + } | ||
305 | + for (AdjacencySid as : adjacencySids) { | ||
306 | + int label = as.getAdjSid(); | ||
307 | + List<Integer> plist = as.getPorts(); | ||
308 | + if (label <= SRGB_MAX) { | ||
309 | + throw new AdjacencyLabelInSRGB(label, dpid); | ||
310 | + } | ||
311 | + if (plist.size() <= 1) { | ||
312 | + throw new AdjacencyLabelNotEnoughPorts(label, dpid); | ||
313 | + } | ||
314 | + } | ||
315 | + | ||
316 | + | ||
317 | + // TODO more validations | ||
318 | + } | ||
319 | + | ||
320 | + /** | ||
321 | + * Setting publishAttributes implies that this is the configuration that | ||
322 | + * will be added to Topology.Switch object before it is published on the | ||
323 | + * channel to other controller instances. | ||
324 | + */ | ||
325 | + private void setPublishAttributes() { | ||
326 | + publishAttributes.put(ROUTER_IP, routerIp); | ||
327 | + publishAttributes.put(ROUTER_MAC, routerMac); | ||
328 | + publishAttributes.put(NODE_SID, String.valueOf(nodeSid)); | ||
329 | + publishAttributes.put(ISEDGE, String.valueOf(isEdgeRouter)); | ||
330 | + ObjectMapper mapper = new ObjectMapper(); | ||
331 | + try { | ||
332 | + publishAttributes.put(ADJACENCY_SIDS, | ||
333 | + mapper.writeValueAsString(adjacencySids)); | ||
334 | + publishAttributes.put(SUBNETS, | ||
335 | + mapper.writeValueAsString(subnets)); | ||
336 | + } catch (JsonProcessingException e) { | ||
337 | + log.error("Error while writing SR config: {}", e.getCause()); | ||
338 | + } catch (IOException e) { | ||
339 | + log.error("Error while writing SR config: {}", e.getCause()); | ||
340 | + } | ||
341 | + } | ||
342 | + | ||
343 | + // ******************** | ||
344 | + // Exceptions | ||
345 | + // ******************** | ||
346 | + | ||
347 | + public static class IpNotSpecified extends RuntimeException { | ||
348 | + private static final long serialVersionUID = -3001502553646331686L; | ||
349 | + | ||
350 | + public IpNotSpecified(DeviceId dpid) { | ||
351 | + super(); | ||
352 | + log.error("Router IP address not specified for SR config dpid:{}", | ||
353 | + dpid); | ||
354 | + } | ||
355 | + } | ||
356 | + | ||
357 | + public static class MacNotSpecified extends RuntimeException { | ||
358 | + private static final long serialVersionUID = -5850132094884129179L; | ||
359 | + | ||
360 | + public MacNotSpecified(DeviceId dpid) { | ||
361 | + super(); | ||
362 | + log.error("Router Mac address not specified for SR config dpid:{}", | ||
363 | + dpid); | ||
364 | + } | ||
365 | + } | ||
366 | + | ||
367 | + public static class UnknownSegmentRouterConfig extends RuntimeException { | ||
368 | + private static final long serialVersionUID = -5750132094884129179L; | ||
369 | + | ||
370 | + public UnknownSegmentRouterConfig(String key, DeviceId dpid) { | ||
371 | + super(); | ||
372 | + log.error("Unknown Segment Router config {} in dpid: {}", key, | ||
373 | + dpid); | ||
374 | + } | ||
375 | + } | ||
376 | + | ||
377 | + public static class SubnetNotSpecifiedInEdgeRouter extends RuntimeException { | ||
378 | + private static final long serialVersionUID = -5855458472668581268L; | ||
379 | + | ||
380 | + public SubnetNotSpecifiedInEdgeRouter(DeviceId dpid) { | ||
381 | + super(); | ||
382 | + log.error("Subnet was not specified for edge router in dpid: {}", | ||
383 | + dpid); | ||
384 | + } | ||
385 | + } | ||
386 | + | ||
387 | + public static class SubnetSpecifiedInBackboneRouter extends RuntimeException { | ||
388 | + private static final long serialVersionUID = 1L; | ||
389 | + | ||
390 | + public SubnetSpecifiedInBackboneRouter(DeviceId dpid) { | ||
391 | + super(); | ||
392 | + log.error("Subnet was specified in backbone router in dpid: {}", | ||
393 | + dpid); | ||
394 | + } | ||
395 | + } | ||
396 | + | ||
397 | + public static class NodeLabelNotInSRGB extends RuntimeException { | ||
398 | + private static final long serialVersionUID = -8482670903748519526L; | ||
399 | + | ||
400 | + public NodeLabelNotInSRGB(int label, DeviceId dpid) { | ||
401 | + super(); | ||
402 | + log.error("Node sif {} specified in not in global label-base " | ||
403 | + + "in dpid: {}", label, | ||
404 | + dpid); | ||
405 | + } | ||
406 | + } | ||
407 | + | ||
408 | + public static class AdjacencyLabelInSRGB extends RuntimeException { | ||
409 | + private static final long serialVersionUID = -8482670903748519526L; | ||
410 | + | ||
411 | + public AdjacencyLabelInSRGB(int label, DeviceId dpid) { | ||
412 | + super(); | ||
413 | + log.error("Adjaceny label {} specified from global label-base " | ||
414 | + + "in dpid: {}", label, | ||
415 | + dpid); | ||
416 | + } | ||
417 | + } | ||
418 | + | ||
419 | + public static class AdjacencyLabelNotEnoughPorts extends RuntimeException { | ||
420 | + private static final long serialVersionUID = -8482670903748519526L; | ||
421 | + | ||
422 | + public AdjacencyLabelNotEnoughPorts(int label, DeviceId dpid) { | ||
423 | + super(); | ||
424 | + log.error("Adjaceny label {} must be specified for at least 2 ports. " | ||
425 | + + "Adjacency labels for single ports are auto-generated " | ||
426 | + + "in dpid: {}", label, | ||
427 | + dpid); | ||
428 | + } | ||
429 | + } | ||
430 | +} |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import java.util.Arrays; | 18 | import java.util.Arrays; |
19 | import java.util.HashSet; | 19 | import java.util.HashSet; | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import static com.google.common.base.Preconditions.checkNotNull; | 18 | import static com.google.common.base.Preconditions.checkNotNull; |
19 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import java.util.Arrays; | 18 | import java.util.Arrays; |
19 | import java.util.HashSet; | 19 | import java.util.HashSet; | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import java.util.List; | 18 | import java.util.List; |
19 | 19 | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import static com.google.common.base.Preconditions.checkNotNull; | 18 | import static com.google.common.base.Preconditions.checkNotNull; |
19 | 19 | ... | ... |
... | @@ -14,7 +14,7 @@ | ... | @@ -14,7 +14,7 @@ |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | -package org.onosproject.grouphandler; | 17 | +package org.onosproject.segmentrouting.grouphandler; |
18 | 18 | ||
19 | import static com.google.common.base.Preconditions.checkNotNull; | 19 | import static com.google.common.base.Preconditions.checkNotNull; |
20 | 20 | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 18 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
... | @@ -26,7 +26,7 @@ import java.util.List; | ... | @@ -26,7 +26,7 @@ import java.util.List; |
26 | import org.onlab.packet.MplsLabel; | 26 | import org.onlab.packet.MplsLabel; |
27 | import org.onosproject.core.ApplicationId; | 27 | import org.onosproject.core.ApplicationId; |
28 | import org.onosproject.core.GroupId; | 28 | import org.onosproject.core.GroupId; |
29 | -import org.onosproject.grouphandler.GroupBucketIdentifier.BucketOutputType; | 29 | +import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; |
30 | import org.onosproject.net.DeviceId; | 30 | import org.onosproject.net.DeviceId; |
31 | import org.onosproject.net.PortNumber; | 31 | import org.onosproject.net.PortNumber; |
32 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 32 | import org.onosproject.net.flow.DefaultTrafficTreatment; | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import java.util.List; | 18 | import java.util.List; |
19 | 19 | ... | ... |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.onosproject.grouphandler; | 16 | +package org.onosproject.segmentrouting.grouphandler; |
17 | 17 | ||
18 | import static com.google.common.base.Preconditions.checkNotNull; | 18 | import static com.google.common.base.Preconditions.checkNotNull; |
19 | 19 | ... | ... |
1 | +{ | ||
2 | + "comment": " Multilayer topology description and configuration", | ||
3 | + "restrictSwitches": true, | ||
4 | + "restrictLinks": true, | ||
5 | + | ||
6 | + "switchConfig": | ||
7 | + [ | ||
8 | + { "nodeDpid" : "of:0000000000000001", "name": "Dallas-R1", "type": "Router_SR", "allowed": true, | ||
9 | + "latitude": 80.80, "longitude": 90.10, | ||
10 | + "params": { "routerIp": "192.168.0.1/32", | ||
11 | + "routerMac": "00:00:01:01:01:80", | ||
12 | + "nodeSid": 101, | ||
13 | + "isEdgeRouter" : true, | ||
14 | + "adjacencySids": [ | ||
15 | + { "ports": [ 4, 5 ], "adjSid": 10234 }, | ||
16 | + { "ports": [ 6, 7 ], "adjSid": 29019 } | ||
17 | + ], | ||
18 | + "subnets": [ | ||
19 | + { "portNo": 1, "subnetIp": "10.0.1.128/24" } | ||
20 | + ] | ||
21 | + } | ||
22 | + }, | ||
23 | + | ||
24 | + { "nodeDpid": "of:0000000000000002", "name": "Dallas-R2", "type": "Router_SR", "allowed": true, | ||
25 | + "latitude": 80.80, "longitude": 90.10, | ||
26 | + "params": { "routerIp": "192.168.0.2/32", | ||
27 | + "routerMac": "00:00:02:02:02:80", | ||
28 | + "nodeSid": 102, | ||
29 | + "isEdgeRouter" : false, | ||
30 | + "adjacencySids": [ | ||
31 | + { "ports": [ 1, 2 ], "adjSid": 12453 }, | ||
32 | + { "ports": [ 2, 3 ], "adjSid": 23333 }, | ||
33 | + { "ports": [ 3, 1 ], "adjSid": 22233 } | ||
34 | + ] | ||
35 | + } | ||
36 | + }, | ||
37 | + | ||
38 | + { "nodeDpid": "of:0000000000000003", "name": "Dallas-R3", "type": "Router_SR", "allowed": true, | ||
39 | + "latitude": 80.80, "longitude": 90.10, | ||
40 | + "params": { "routerIp": "192.168.0.3/32", | ||
41 | + "routerMac": "00:00:03:03:03:80", | ||
42 | + "nodeSid": 103, | ||
43 | + "isEdgeRouter" : false | ||
44 | + } | ||
45 | + }, | ||
46 | + | ||
47 | + { "nodeDpid": "of:0000000000000004", "name": "Dallas-R4", "type": "Router_SR", "allowed": true, | ||
48 | + "latitude": 80.80, "longitude": 90.10, | ||
49 | + "params": { "routerIp": "192.168.0.4/32", | ||
50 | + "routerMac": "00:00:04:04:04:80", | ||
51 | + "nodeSid": 104, | ||
52 | + "isEdgeRouter" : false | ||
53 | + } | ||
54 | + }, | ||
55 | + | ||
56 | + { "nodeDpid": "of:0000000000000005", "name": "Dallas-R5", "type": "Router_SR", "allowed": true, | ||
57 | + "latitude": 80.80, "longitude": 90.10, | ||
58 | + "params": { "routerIp": "192.168.0.5/32", | ||
59 | + "routerMac": "00:00:05:05:05:80", | ||
60 | + "nodeSid": 105, | ||
61 | + "isEdgeRouter" : false | ||
62 | + } | ||
63 | + }, | ||
64 | + | ||
65 | + { "nodeDpid": "of:0000000000000006", "name": "Dallas-R6", "type": "Router_SR", "allowed": true, | ||
66 | + "latitude": 80.80, "longitude": 90.10, | ||
67 | + "params": { "routerIp": "192.168.0.6/32", | ||
68 | + "routerMac": "00:00:07:07:07:80", | ||
69 | + "nodeSid": 106, | ||
70 | + "isEdgeRouter" : true, | ||
71 | + "subnets": [ | ||
72 | + { "portNo": 1, "subnetIp": "7.7.7.128/24" } | ||
73 | + ] | ||
74 | + } | ||
75 | + } | ||
76 | + | ||
77 | + ] | ||
78 | +} |
-
Please register or login to post a comment