blob: 21734960bf9898a664c0478a817670671b87114c [file] [log] [blame]
sunishvkf7c56552016-07-18 16:02:39 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
sunishvkf7c56552016-07-18 16:02:39 +05303 *
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 */
16package org.onosproject.ospf.controller.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import org.onlab.packet.Ip4Address;
20import org.onosproject.ospf.controller.OspfArea;
21import org.onosproject.ospf.controller.OspfInterface;
22import org.onosproject.ospf.controller.OspfProcess;
23import org.onosproject.ospf.controller.area.OspfAreaImpl;
24import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
25import org.onosproject.ospf.controller.area.OspfProcessImpl;
26import org.onosproject.ospf.protocol.util.OspfUtil;
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
30import java.net.InetAddress;
31import java.net.NetworkInterface;
32import java.util.ArrayList;
33import java.util.Enumeration;
34import java.util.List;
35
36/**
37 * Representation of OSPF network configuration parsing util.
38 */
39public final class OspfConfigUtil {
40 public static final String PROCESSID = "processId";
41 public static final String AREAS = "areas";
42 public static final String INTERFACEINDEX = "interfaceIndex";
43 public static final String AREAID = "areaId";
44 public static final String ROUTERID = "routerId";
45 public static final String INTERFACE = "interface";
46 public static final String HELLOINTERVAL = "helloIntervalTime";
47 public static final String ROUTERDEADINTERVAL = "routerDeadIntervalTime";
48 public static final String INTERFACETYPE = "interfaceType";
49 public static final String EXTERNALROUTINGCAPABILITY = "externalRoutingCapability";
Ray Milkey9c9cde42018-01-12 14:22:06 -080050 private static final Logger log = LoggerFactory.getLogger(OspfConfigUtil.class);
sunishvkf7c56552016-07-18 16:02:39 +053051 private static final String ISOPAQUE = "isOpaqueEnable";
52
53 /**
54 * Creates an instance of this.
55 */
56 private OspfConfigUtil() {
57
58 }
59
60 /**
61 * Returns list of OSPF process from the json nodes.
62 *
63 * @param jsonNodes represents one or more OSPF process configuration
64 * @return list of OSPF processes.
65 */
66 public static List<OspfProcess> processes(JsonNode jsonNodes) {
67 List<OspfProcess> ospfProcesses = new ArrayList<>();
68 if (jsonNodes == null) {
69 return ospfProcesses;
70 }
71 //From each Process nodes, get area and related interface details.
72 jsonNodes.forEach(jsonNode -> {
73 List<OspfArea> areas = new ArrayList<>();
74 //Get configured areas for the process.
75 for (JsonNode areaNode : jsonNode.path(AREAS)) {
76 List<OspfInterface> interfaceList = new ArrayList<>();
77 for (JsonNode interfaceNode : areaNode.path(INTERFACE)) {
78 OspfInterface ospfInterface = interfaceDetails(interfaceNode);
79 if (ospfInterface != null) {
80 interfaceList.add(ospfInterface);
81 }
82 }
83 //Get the area details
84 OspfArea area = areaDetails(areaNode);
85 if (area != null) {
86 area.setOspfInterfaceList(interfaceList);
87 areas.add(area);
88 }
89 }
90 OspfProcess process = new OspfProcessImpl();
91 process.setProcessId(jsonNode.path(PROCESSID).asText());
92 process.setAreas(areas);
93 ospfProcesses.add(process);
94 });
95
96 return ospfProcesses;
97 }
98
99 /**
100 * Returns interface IP by index.
101 *
102 * @param interfaceIndex interface index
103 * @return interface IP by index
104 */
105 private static Ip4Address getInterfaceIp(int interfaceIndex) {
106 Ip4Address ipAddress = null;
107 try {
108 NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
109 Enumeration ipAddresses = networkInterface.getInetAddresses();
110 while (ipAddresses.hasMoreElements()) {
111 InetAddress address = (InetAddress) ipAddresses.nextElement();
112 if (!address.isLinkLocalAddress()) {
113 ipAddress = Ip4Address.valueOf(address.getAddress());
114 break;
115 }
116 }
117 } catch (Exception e) {
118 log.debug("Error while getting Interface IP by index");
119 return OspfUtil.DEFAULTIP;
120 }
121 return ipAddress;
122 }
123
124 /**
125 * Returns interface MAC by index.
126 *
127 * @param interfaceIndex interface index
128 * @return interface IP by index
129 */
130 private static String getInterfaceMask(int interfaceIndex) {
131 String subnetMask = null;
132 try {
133 Ip4Address ipAddress = getInterfaceIp(interfaceIndex);
134 NetworkInterface networkInterface = NetworkInterface.getByInetAddress(
135 InetAddress.getByName(ipAddress.toString()));
136 Enumeration ipAddresses = networkInterface.getInetAddresses();
137 int index = 0;
138 while (ipAddresses.hasMoreElements()) {
139 InetAddress address = (InetAddress) ipAddresses.nextElement();
140 if (!address.isLinkLocalAddress()) {
141 break;
142 }
143 index++;
144 }
145 int prfLen = networkInterface.getInterfaceAddresses().get(index).getNetworkPrefixLength();
146 int shft = 0xffffffff << (32 - prfLen);
147 int oct1 = ((byte) ((shft & 0xff000000) >> 24)) & 0xff;
148 int oct2 = ((byte) ((shft & 0x00ff0000) >> 16)) & 0xff;
149 int oct3 = ((byte) ((shft & 0x0000ff00) >> 8)) & 0xff;
150 int oct4 = ((byte) (shft & 0x000000ff)) & 0xff;
151 subnetMask = oct1 + "." + oct2 + "." + oct3 + "." + oct4;
152 } catch (Exception e) {
153 log.debug("Error while getting Interface network mask by index");
154 return subnetMask;
155 }
156 return subnetMask;
157 }
158
159 /**
160 * Checks if valid digit or not.
161 *
162 * @param strInput input value
163 * @return true if valid else false
164 */
165 private static boolean isValidDigit(String strInput) {
166 boolean isValid = true;
167 if (isPrimitive(strInput)) {
168 int input = Integer.parseInt(strInput);
169 if (input < 1 || input > 255) {
170 log.debug("Wrong config input value: {}", strInput);
171 isValid = false;
172 } else {
173 isValid = true;
174 }
175
176 } else {
177 isValid = false;
178 }
179
180 return isValid;
181 }
182
183 /**
184 * Checks if primitive or not.
185 *
186 * @param value input value
187 * @return true if number else false
188 */
189 private static boolean isPrimitive(String value) {
190 boolean status = true;
191 value = value.trim();
192 if (value.length() < 1) {
193 return false;
194 }
195 for (int i = 0; i < value.length(); i++) {
196 char c = value.charAt(i);
197 if (!Character.isDigit(c)) {
198 status = false;
199 break;
200 }
201 }
202
203 return status;
204 }
205
206 /**
207 * Checks if boolean or not.
208 *
209 * @param value input value
210 * @return true if boolean else false
211 */
212 private static boolean isBoolean(String value) {
213 boolean status = false;
214 value = value.trim();
215 if (value.equals("true") || value.equals("false")) {
216 return true;
217 }
218
219 return status;
220 }
221
222 /**
223 * Checks if given id is valid or not.
224 *
225 * @param value input value
226 * @return true if valid else false
227 */
228 private static boolean isValidIpAddress(String value) {
229 boolean status = true;
230 try {
231 Ip4Address ipAddress = Ip4Address.valueOf(value);
232 } catch (Exception e) {
233 log.debug("Invalid IP address string: {}", value);
234 return false;
235 }
236
237 return status;
238 }
239
240 /**
241 * Returns OSPF area instance from configuration.
242 *
243 * @param areaNode area configuration
244 * @return OSPF area instance
245 */
246 private static OspfArea areaDetails(JsonNode areaNode) {
247 OspfArea area = new OspfAreaImpl();
248 String areaId = areaNode.path(AREAID).asText();
249 if (isValidIpAddress(areaId)) {
250 area.setAreaId(Ip4Address.valueOf(areaId));
251 } else {
252 log.debug("Wrong areaId: {}", areaId);
253 return null;
254 }
255 String routerId = areaNode.path(ROUTERID).asText();
256 if (isValidIpAddress(routerId)) {
257 area.setRouterId(Ip4Address.valueOf(routerId));
258 } else {
259 log.debug("Wrong routerId: {}", routerId);
260 return null;
261 }
262 String routingCapability = areaNode.path(EXTERNALROUTINGCAPABILITY).asText();
263 if (isBoolean(routingCapability)) {
264 area.setExternalRoutingCapability(Boolean.valueOf(routingCapability));
265 } else {
266 log.debug("Wrong routingCapability: {}", routingCapability);
267 return null;
268 }
269 String isOpaqueEnabled = areaNode.path(ISOPAQUE).asText();
270 if (isBoolean(isOpaqueEnabled)) {
271 area.setIsOpaqueEnabled(Boolean.valueOf(isOpaqueEnabled));
272 } else {
273 log.debug("Wrong isOpaqueEnabled: {}", isOpaqueEnabled);
274 return null;
275 }
276 area.setOptions(OspfUtil.HELLO_PACKET_OPTIONS);
277
278 return area;
279 }
280
281 /**
282 * Returns OSPF interface instance from configuration.
283 *
284 * @param interfaceNode interface configuration
285 * @return OSPF interface instance
286 */
287 private static OspfInterface interfaceDetails(JsonNode interfaceNode) {
288 OspfInterface ospfInterface = new OspfInterfaceImpl();
289 String index = interfaceNode.path(INTERFACEINDEX).asText();
290 if (isValidDigit(index)) {
291 ospfInterface.setInterfaceIndex(Integer.parseInt(index));
292 } else {
293 log.debug("Wrong interface index: {}", index);
294 return null;
295 }
296 Ip4Address interfaceIp = getInterfaceIp(ospfInterface.interfaceIndex());
297 if (interfaceIp.equals(OspfUtil.DEFAULTIP)) {
298 return null;
299 }
300 ospfInterface.setIpAddress(interfaceIp);
301 ospfInterface.setIpNetworkMask(Ip4Address.valueOf(getInterfaceMask(
302 ospfInterface.interfaceIndex())));
303 ospfInterface.setBdr(OspfUtil.DEFAULTIP);
304 ospfInterface.setDr(OspfUtil.DEFAULTIP);
305 String helloInterval = interfaceNode.path(HELLOINTERVAL).asText();
306 if (isValidDigit(helloInterval)) {
307 ospfInterface.setHelloIntervalTime(Integer.parseInt(helloInterval));
308 } else {
309 log.debug("Wrong hello interval: {}", helloInterval);
310 return null;
311 }
312 String routerDeadInterval = interfaceNode.path(ROUTERDEADINTERVAL).asText();
313 if (isValidDigit(routerDeadInterval)) {
314 ospfInterface.setRouterDeadIntervalTime(Integer.parseInt(routerDeadInterval));
315 } else {
316 log.debug("Wrong routerDeadInterval: {}", routerDeadInterval);
317 return null;
318 }
319 String interfaceType = interfaceNode.path(INTERFACETYPE).asText();
320 if (isValidDigit(interfaceType)) {
321 ospfInterface.setInterfaceType(Integer.parseInt(interfaceType));
322 } else {
323 log.debug("Wrong interfaceType: {}", interfaceType);
324 return null;
325 }
326 ospfInterface.setReTransmitInterval(OspfUtil.RETRANSMITINTERVAL);
327 ospfInterface.setMtu(OspfUtil.MTU);
328 ospfInterface.setRouterPriority(OspfUtil.ROUTER_PRIORITY);
329
330 return ospfInterface;
331 }
332}