blob: 21734960bf9898a664c0478a817670671b87114c [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.ospf.controller.impl;
import com.fasterxml.jackson.databind.JsonNode;
import org.onlab.packet.Ip4Address;
import org.onosproject.ospf.controller.OspfArea;
import org.onosproject.ospf.controller.OspfInterface;
import org.onosproject.ospf.controller.OspfProcess;
import org.onosproject.ospf.controller.area.OspfAreaImpl;
import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
import org.onosproject.ospf.controller.area.OspfProcessImpl;
import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* Representation of OSPF network configuration parsing util.
*/
public final class OspfConfigUtil {
public static final String PROCESSID = "processId";
public static final String AREAS = "areas";
public static final String INTERFACEINDEX = "interfaceIndex";
public static final String AREAID = "areaId";
public static final String ROUTERID = "routerId";
public static final String INTERFACE = "interface";
public static final String HELLOINTERVAL = "helloIntervalTime";
public static final String ROUTERDEADINTERVAL = "routerDeadIntervalTime";
public static final String INTERFACETYPE = "interfaceType";
public static final String EXTERNALROUTINGCAPABILITY = "externalRoutingCapability";
private static final Logger log = LoggerFactory.getLogger(OspfConfigUtil.class);
private static final String ISOPAQUE = "isOpaqueEnable";
/**
* Creates an instance of this.
*/
private OspfConfigUtil() {
}
/**
* Returns list of OSPF process from the json nodes.
*
* @param jsonNodes represents one or more OSPF process configuration
* @return list of OSPF processes.
*/
public static List<OspfProcess> processes(JsonNode jsonNodes) {
List<OspfProcess> ospfProcesses = new ArrayList<>();
if (jsonNodes == null) {
return ospfProcesses;
}
//From each Process nodes, get area and related interface details.
jsonNodes.forEach(jsonNode -> {
List<OspfArea> areas = new ArrayList<>();
//Get configured areas for the process.
for (JsonNode areaNode : jsonNode.path(AREAS)) {
List<OspfInterface> interfaceList = new ArrayList<>();
for (JsonNode interfaceNode : areaNode.path(INTERFACE)) {
OspfInterface ospfInterface = interfaceDetails(interfaceNode);
if (ospfInterface != null) {
interfaceList.add(ospfInterface);
}
}
//Get the area details
OspfArea area = areaDetails(areaNode);
if (area != null) {
area.setOspfInterfaceList(interfaceList);
areas.add(area);
}
}
OspfProcess process = new OspfProcessImpl();
process.setProcessId(jsonNode.path(PROCESSID).asText());
process.setAreas(areas);
ospfProcesses.add(process);
});
return ospfProcesses;
}
/**
* Returns interface IP by index.
*
* @param interfaceIndex interface index
* @return interface IP by index
*/
private static Ip4Address getInterfaceIp(int interfaceIndex) {
Ip4Address ipAddress = null;
try {
NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
Enumeration ipAddresses = networkInterface.getInetAddresses();
while (ipAddresses.hasMoreElements()) {
InetAddress address = (InetAddress) ipAddresses.nextElement();
if (!address.isLinkLocalAddress()) {
ipAddress = Ip4Address.valueOf(address.getAddress());
break;
}
}
} catch (Exception e) {
log.debug("Error while getting Interface IP by index");
return OspfUtil.DEFAULTIP;
}
return ipAddress;
}
/**
* Returns interface MAC by index.
*
* @param interfaceIndex interface index
* @return interface IP by index
*/
private static String getInterfaceMask(int interfaceIndex) {
String subnetMask = null;
try {
Ip4Address ipAddress = getInterfaceIp(interfaceIndex);
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(
InetAddress.getByName(ipAddress.toString()));
Enumeration ipAddresses = networkInterface.getInetAddresses();
int index = 0;
while (ipAddresses.hasMoreElements()) {
InetAddress address = (InetAddress) ipAddresses.nextElement();
if (!address.isLinkLocalAddress()) {
break;
}
index++;
}
int prfLen = networkInterface.getInterfaceAddresses().get(index).getNetworkPrefixLength();
int shft = 0xffffffff << (32 - prfLen);
int oct1 = ((byte) ((shft & 0xff000000) >> 24)) & 0xff;
int oct2 = ((byte) ((shft & 0x00ff0000) >> 16)) & 0xff;
int oct3 = ((byte) ((shft & 0x0000ff00) >> 8)) & 0xff;
int oct4 = ((byte) (shft & 0x000000ff)) & 0xff;
subnetMask = oct1 + "." + oct2 + "." + oct3 + "." + oct4;
} catch (Exception e) {
log.debug("Error while getting Interface network mask by index");
return subnetMask;
}
return subnetMask;
}
/**
* Checks if valid digit or not.
*
* @param strInput input value
* @return true if valid else false
*/
private static boolean isValidDigit(String strInput) {
boolean isValid = true;
if (isPrimitive(strInput)) {
int input = Integer.parseInt(strInput);
if (input < 1 || input > 255) {
log.debug("Wrong config input value: {}", strInput);
isValid = false;
} else {
isValid = true;
}
} else {
isValid = false;
}
return isValid;
}
/**
* Checks if primitive or not.
*
* @param value input value
* @return true if number else false
*/
private static boolean isPrimitive(String value) {
boolean status = true;
value = value.trim();
if (value.length() < 1) {
return false;
}
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (!Character.isDigit(c)) {
status = false;
break;
}
}
return status;
}
/**
* Checks if boolean or not.
*
* @param value input value
* @return true if boolean else false
*/
private static boolean isBoolean(String value) {
boolean status = false;
value = value.trim();
if (value.equals("true") || value.equals("false")) {
return true;
}
return status;
}
/**
* Checks if given id is valid or not.
*
* @param value input value
* @return true if valid else false
*/
private static boolean isValidIpAddress(String value) {
boolean status = true;
try {
Ip4Address ipAddress = Ip4Address.valueOf(value);
} catch (Exception e) {
log.debug("Invalid IP address string: {}", value);
return false;
}
return status;
}
/**
* Returns OSPF area instance from configuration.
*
* @param areaNode area configuration
* @return OSPF area instance
*/
private static OspfArea areaDetails(JsonNode areaNode) {
OspfArea area = new OspfAreaImpl();
String areaId = areaNode.path(AREAID).asText();
if (isValidIpAddress(areaId)) {
area.setAreaId(Ip4Address.valueOf(areaId));
} else {
log.debug("Wrong areaId: {}", areaId);
return null;
}
String routerId = areaNode.path(ROUTERID).asText();
if (isValidIpAddress(routerId)) {
area.setRouterId(Ip4Address.valueOf(routerId));
} else {
log.debug("Wrong routerId: {}", routerId);
return null;
}
String routingCapability = areaNode.path(EXTERNALROUTINGCAPABILITY).asText();
if (isBoolean(routingCapability)) {
area.setExternalRoutingCapability(Boolean.valueOf(routingCapability));
} else {
log.debug("Wrong routingCapability: {}", routingCapability);
return null;
}
String isOpaqueEnabled = areaNode.path(ISOPAQUE).asText();
if (isBoolean(isOpaqueEnabled)) {
area.setIsOpaqueEnabled(Boolean.valueOf(isOpaqueEnabled));
} else {
log.debug("Wrong isOpaqueEnabled: {}", isOpaqueEnabled);
return null;
}
area.setOptions(OspfUtil.HELLO_PACKET_OPTIONS);
return area;
}
/**
* Returns OSPF interface instance from configuration.
*
* @param interfaceNode interface configuration
* @return OSPF interface instance
*/
private static OspfInterface interfaceDetails(JsonNode interfaceNode) {
OspfInterface ospfInterface = new OspfInterfaceImpl();
String index = interfaceNode.path(INTERFACEINDEX).asText();
if (isValidDigit(index)) {
ospfInterface.setInterfaceIndex(Integer.parseInt(index));
} else {
log.debug("Wrong interface index: {}", index);
return null;
}
Ip4Address interfaceIp = getInterfaceIp(ospfInterface.interfaceIndex());
if (interfaceIp.equals(OspfUtil.DEFAULTIP)) {
return null;
}
ospfInterface.setIpAddress(interfaceIp);
ospfInterface.setIpNetworkMask(Ip4Address.valueOf(getInterfaceMask(
ospfInterface.interfaceIndex())));
ospfInterface.setBdr(OspfUtil.DEFAULTIP);
ospfInterface.setDr(OspfUtil.DEFAULTIP);
String helloInterval = interfaceNode.path(HELLOINTERVAL).asText();
if (isValidDigit(helloInterval)) {
ospfInterface.setHelloIntervalTime(Integer.parseInt(helloInterval));
} else {
log.debug("Wrong hello interval: {}", helloInterval);
return null;
}
String routerDeadInterval = interfaceNode.path(ROUTERDEADINTERVAL).asText();
if (isValidDigit(routerDeadInterval)) {
ospfInterface.setRouterDeadIntervalTime(Integer.parseInt(routerDeadInterval));
} else {
log.debug("Wrong routerDeadInterval: {}", routerDeadInterval);
return null;
}
String interfaceType = interfaceNode.path(INTERFACETYPE).asText();
if (isValidDigit(interfaceType)) {
ospfInterface.setInterfaceType(Integer.parseInt(interfaceType));
} else {
log.debug("Wrong interfaceType: {}", interfaceType);
return null;
}
ospfInterface.setReTransmitInterval(OspfUtil.RETRANSMITINTERVAL);
ospfInterface.setMtu(OspfUtil.MTU);
ospfInterface.setRouterPriority(OspfUtil.ROUTER_PRIORITY);
return ospfInterface;
}
}