blob: 2020dea87098761f07f2a3dcfeec6eaaaa4bb759 [file] [log] [blame]
Saurav Dasfb93c252014-08-18 20:40:13 -07001package net.onrc.onos.core.configmanager;
2
3import java.io.IOException;
4import java.util.ArrayList;
5import java.util.Iterator;
6import java.util.List;
7import java.util.Map.Entry;
8import java.util.Set;
9import java.util.concurrent.ConcurrentHashMap;
10
11import net.onrc.onos.core.configmanager.NetworkConfig.SwitchConfig;
12
13import org.codehaus.jackson.JsonNode;
14import org.codehaus.jackson.JsonProcessingException;
15import org.codehaus.jackson.map.ObjectMapper;
16import org.projectfloodlight.openflow.util.HexString;
17import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
19
20public class SegmentRouterConfig extends SwitchConfig {
21 protected static final Logger log = LoggerFactory
22 .getLogger(SegmentRouterConfig.class);
23 private String routerIp;
24 private String routerMac;
25 private int nodeSid;
Sangho Shindafae192014-10-07 17:06:48 -070026 private boolean isEdgeRouter;
Saurav Dasfb93c252014-08-18 20:40:13 -070027 private List<AdjacencySid> adjacencySids;
28 private List<Subnet> subnets;
29
30 public static final String ROUTER_IP = "routerIp";
31 public static final String ROUTER_MAC = "routerMac";
32 public static final String NODE_SID = "nodeSid";
33 public static final String ADJACENCY_SIDS = "adjacencySids";
34 public static final String SUBNETS = "subnets";
Sangho Shindafae192014-10-07 17:06:48 -070035 public static final String ISEDGE = "isEdgeRouter";
Saurav Das2d41a432014-10-21 20:40:10 -070036 private static final int SRGB_MAX = 1000;
Saurav Dasfb93c252014-08-18 20:40:13 -070037
38 public SegmentRouterConfig(SwitchConfig swc) {
39 this.setName(swc.getName());
40 this.setDpid(swc.getDpid());
41 this.setType(swc.getType());
42 this.setLatitude(swc.getLatitude());
43 this.setLongitude(swc.getLongitude());
44 this.setParams(swc.getParams());
45 this.setAllowed(swc.isAllowed());
46 publishAttributes = new ConcurrentHashMap<String, String>();
47 adjacencySids = new ArrayList<AdjacencySid>();
48 subnets = new ArrayList<Subnet>();
49 parseParams();
50 validateParams();
51 setPublishAttributes();
52 }
53
54 // ********************
55 // Segment Router Configuration
56 // ********************
57 public String getRouterIp() {
58 return routerIp;
59 }
60
61 public void setRouterIp(String routerIp) {
62 this.routerIp = routerIp;
63 }
64
65 public String getRouterMac() {
66 return routerMac;
67 }
68
69 public void setRouterMac(String routerMac) {
70 this.routerMac = routerMac;
71 }
72
73 public int getNodeSid() {
74 return nodeSid;
75 }
76
77 public void setNodeSid(int nodeSid) {
78 this.nodeSid = nodeSid;
79 }
80
Sangho Shindafae192014-10-07 17:06:48 -070081 public boolean isEdgeRouter() {
82 return isEdgeRouter;
83 }
84
85 public void setIsEdgeRouter(boolean isEdge) {
86 this.isEdgeRouter = isEdge;
87 }
88
Saurav Dasfb93c252014-08-18 20:40:13 -070089 public static class AdjacencySid {
Saurav Dasfb93c252014-08-18 20:40:13 -070090 private int adjSid;
Saurav Das2d41a432014-10-21 20:40:10 -070091 private List<Integer> ports;
Saurav Dasfb93c252014-08-18 20:40:13 -070092
Saurav Das2d41a432014-10-21 20:40:10 -070093 public AdjacencySid(int adjSid, List<Integer> ports) {
94 this.ports = ports;
Saurav Dasfb93c252014-08-18 20:40:13 -070095 this.adjSid = adjSid;
96 }
97
Saurav Das2d41a432014-10-21 20:40:10 -070098 public List<Integer> getPorts() {
99 return ports;
Saurav Dasfb93c252014-08-18 20:40:13 -0700100 }
101
Saurav Das2d41a432014-10-21 20:40:10 -0700102 public void setPorts(List<Integer> ports) {
103 this.ports = ports;
Saurav Dasfb93c252014-08-18 20:40:13 -0700104 }
105
106 public int getAdjSid() {
107 return adjSid;
108 }
109
110 public void setAdjSid(int adjSid) {
111 this.adjSid = adjSid;
112 }
113 }
114
115 public List<AdjacencySid> getAdjacencySids() {
116 return adjacencySids;
117 }
118
119 public void setAdjacencySids(List<AdjacencySid> adjacencySids) {
120 this.adjacencySids = adjacencySids;
121 }
122
123 public static class Subnet {
124 private int portNo;
125 private String subnetIp;
126
127 public Subnet(int portNo, String subnetIp) {
128 this.portNo = portNo;
129 this.subnetIp = subnetIp;
130 }
131
132 public int getPortNo() {
133 return portNo;
134 }
135
136 public void setPortNo(int portNo) {
137 this.portNo = portNo;
138 }
139
140 public String getSubnetIp() {
141 return subnetIp;
142 }
143
144 public void setSubnetIp(String subnetIp) {
145 this.subnetIp = subnetIp;
146 }
147 }
148
149 public List<Subnet> getSubnets() {
150 return subnets;
151 }
152
153 public void setSubnets(List<Subnet> subnets) {
154 this.subnets = subnets;
155 }
156
157 // ********************
158 // Helper methods
159 // ********************
160
161 private void parseParams() {
162 if (params == null) {
163 throw new NetworkConfigException.ParamsNotSpecified(name);
164 }
165
166 Set<Entry<String, JsonNode>> m = params.entrySet();
167 for (Entry<String, JsonNode> e : m) {
168 String key = e.getKey();
169 JsonNode j = e.getValue();
170 if (key.equals("routerIp")) {
171 setRouterIp(j.asText());
172 } else if (key.equals("routerMac")) {
173 setRouterMac(j.asText());
174 } else if (key.equals("nodeSid")) {
175 setNodeSid(j.asInt());
Sangho Shindafae192014-10-07 17:06:48 -0700176 } else if (key.equals("isEdgeRouter")) {
177 setIsEdgeRouter(j.asBoolean());
178 }
179 else if (key.equals("adjacencySids") || key.equals("subnets")) {
Saurav Dasfb93c252014-08-18 20:40:13 -0700180 getInnerParams(j, key);
181 } else {
182 throw new UnknownSegmentRouterConfig(key, dpid);
183 }
184 }
185 }
186
187 private void getInnerParams(JsonNode j, String innerParam) {
188 Iterator<JsonNode> innerList = j.getElements();
189 while (innerList.hasNext()) {
190 Iterator<Entry<String, JsonNode>> f = innerList.next().getFields();
191 int portNo = -1;
192 int adjSid = -1;
193 String subnetIp = null;
Saurav Das2d41a432014-10-21 20:40:10 -0700194 List<Integer> ports = null;
Saurav Dasfb93c252014-08-18 20:40:13 -0700195 while (f.hasNext()) {
196 Entry<String, JsonNode> fe = f.next();
197 if (fe.getKey().equals("portNo")) {
198 portNo = fe.getValue().asInt();
199 } else if (fe.getKey().equals("adjSid")) {
200 adjSid = fe.getValue().asInt();
201 } else if (fe.getKey().equals("subnetIp")) {
202 subnetIp = fe.getValue().asText();
Saurav Das2d41a432014-10-21 20:40:10 -0700203 } else if (fe.getKey().equals("ports")) {
204 if (fe.getValue().isArray()) {
205 Iterator<JsonNode> i = fe.getValue().getElements();
206 ports = new ArrayList<Integer>();
207 while (i.hasNext()) {
208 ports.add(i.next().asInt());
209 }
210 }
Saurav Dasfb93c252014-08-18 20:40:13 -0700211 } else {
212 throw new UnknownSegmentRouterConfig(fe.getKey(), dpid);
213 }
214 }
215 if (innerParam.equals("adjacencySids")) {
Saurav Das2d41a432014-10-21 20:40:10 -0700216 AdjacencySid ads = new AdjacencySid(adjSid, ports);
Saurav Dasfb93c252014-08-18 20:40:13 -0700217 adjacencySids.add(ads);
218 } else {
219 Subnet sip = new Subnet(portNo, subnetIp);
220 subnets.add(sip);
221 }
222 }
223 }
224
225 private void validateParams() {
226 if (routerIp == null) {
227 throw new IpNotSpecified(dpid);
228 }
Sangho Shindafae192014-10-07 17:06:48 -0700229 if (isEdgeRouter && subnets.isEmpty()) {
230 throw new SubnetNotSpecifiedInEdgeRouter(dpid);
231 }
232 if (!isEdgeRouter && !subnets.isEmpty()) {
233 throw new SubnetSpecifiedInBackboneRouter(dpid);
234 }
Saurav Das2d41a432014-10-21 20:40:10 -0700235 if (nodeSid > SRGB_MAX) {
236 throw new NodeLabelNotInSRGB(nodeSid, dpid);
237 }
238 for (AdjacencySid as : adjacencySids) {
239 int label = as.getAdjSid();
240 List<Integer> plist = as.getPorts();
241 if (label <= SRGB_MAX) {
242 throw new AdjacencyLabelInSRGB(label, dpid);
243 }
244 if (plist.size() <= 1) {
245 throw new AdjacencyLabelNotEnoughPorts(label, dpid);
246 }
247 }
248
Saurav Dasfb93c252014-08-18 20:40:13 -0700249
250 // TODO more validations
251 }
252
253 /**
254 * Setting publishAttributes implies that this is the configuration that
255 * will be added to Topology.Switch object before it is published on the
256 * channel to other controller instances.
257 */
258 private void setPublishAttributes() {
259 publishAttributes.put(ROUTER_IP, routerIp);
260 publishAttributes.put(ROUTER_MAC, routerMac);
261 publishAttributes.put(NODE_SID, String.valueOf(nodeSid));
Sangho Shindafae192014-10-07 17:06:48 -0700262 publishAttributes.put(ISEDGE, String.valueOf(isEdgeRouter));
Saurav Dasfb93c252014-08-18 20:40:13 -0700263 ObjectMapper mapper = new ObjectMapper();
264 try {
265 publishAttributes.put(ADJACENCY_SIDS,
266 mapper.writeValueAsString(adjacencySids));
267 publishAttributes.put(SUBNETS,
268 mapper.writeValueAsString(subnets));
269 } catch (JsonProcessingException e) {
270 log.error("Error while writing SR config: {}", e.getCause());
271 } catch (IOException e) {
272 log.error("Error while writing SR config: {}", e.getCause());
273 }
274 }
275
276 // ********************
277 // Exceptions
278 // ********************
279
280 public static class IpNotSpecified extends RuntimeException {
281 private static final long serialVersionUID = -3001502553646331686L;
282
283 public IpNotSpecified(long dpid) {
284 super();
285 log.error("Router IP address not specified for SR config dpid:{}",
286 HexString.toHexString(dpid));
287 }
288 }
289
290 public static class UnknownSegmentRouterConfig extends RuntimeException {
291 private static final long serialVersionUID = -5750132094884129179L;
292
293 public UnknownSegmentRouterConfig(String key, long dpid) {
294 super();
295 log.error("Unknown Segment Router config {} in dpid: {}", key,
296 HexString.toHexString(dpid));
297 }
298 }
299
Sangho Shindafae192014-10-07 17:06:48 -0700300 public static class SubnetNotSpecifiedInEdgeRouter extends RuntimeException {
301 private static final long serialVersionUID = -5855458472668581268L;
302
303 public SubnetNotSpecifiedInEdgeRouter(long dpid) {
304 super();
305 log.error("Subnet was not specified for edge router in dpid: {}",
306 HexString.toHexString(dpid));
307 }
308 }
309
310 public static class SubnetSpecifiedInBackboneRouter extends RuntimeException {
Saurav Das2d41a432014-10-21 20:40:10 -0700311 private static final long serialVersionUID = 1L;
Sangho Shindafae192014-10-07 17:06:48 -0700312
313 public SubnetSpecifiedInBackboneRouter(long dpid) {
314 super();
315 log.error("Subnet was specified in backbone router in dpid: {}",
316 HexString.toHexString(dpid));
317 }
318 }
319
Saurav Das2d41a432014-10-21 20:40:10 -0700320 public static class NodeLabelNotInSRGB extends RuntimeException {
321 private static final long serialVersionUID = -8482670903748519526L;
Sangho Shindafae192014-10-07 17:06:48 -0700322
Saurav Das2d41a432014-10-21 20:40:10 -0700323 public NodeLabelNotInSRGB(int label, long dpid) {
324 super();
325 log.error("Node sif {} specified in not in global label-base "
326 + "in dpid: {}", label,
327 HexString.toHexString(dpid));
328 }
329 }
Saurav Dasfb93c252014-08-18 20:40:13 -0700330
Saurav Das2d41a432014-10-21 20:40:10 -0700331 public static class AdjacencyLabelInSRGB extends RuntimeException {
332 private static final long serialVersionUID = -8482670903748519526L;
333
334 public AdjacencyLabelInSRGB(int label, long dpid) {
335 super();
336 log.error("Adjaceny label {} specified from global label-base "
337 + "in dpid: {}", label,
338 HexString.toHexString(dpid));
339 }
340 }
341
342 public static class AdjacencyLabelNotEnoughPorts extends RuntimeException {
343 private static final long serialVersionUID = -8482670903748519526L;
344
345 public AdjacencyLabelNotEnoughPorts(int label, long dpid) {
346 super();
347 log.error("Adjaceny label {} must be specified for at least 2 ports. "
348 + "Adjacency labels for single ports are auto-generated "
349 + "in dpid: {}", label,
350 HexString.toHexString(dpid));
351 }
352 }
Saurav Dasfb93c252014-08-18 20:40:13 -0700353}