blob: 9ddef5a5ff1fc14763b9d3322006f293e2ff3cd8 [file] [log] [blame]
/*
* Copyright 2016 Open Networking Laboratory
*
* 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.protocol.lsa.types;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.primitives.Bytes;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.ospf.exceptions.OspfErrorType;
import org.onosproject.ospf.exceptions.OspfParseException;
import org.onosproject.ospf.protocol.lsa.LsaHeader;
import org.onosproject.ospf.protocol.lsa.subtypes.OspfLsaLink;
import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
/**
* Representation of a Router LSA, and the fields and methods to access them.
*/
public class RouterLsa extends LsaHeader {
/*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| LS age | Options | 1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Link State ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Advertising Router |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| LS sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| LS checksum | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0 |V|E|B| 0 | # links |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Link ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Link Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | # TOS | metric |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| TOS | 0 | TOS metric |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Link ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Link Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ... |
*/
private static final Logger log =
LoggerFactory.getLogger(RouterLsa.class);
private boolean isVirtualEndPoint;
private boolean isAsBoundaryRouter;
private boolean isAreaBorderRouter;
private int noLink;
private List<OspfLsaLink> routerLinks = new ArrayList<>();
/**
* Creates an instance of Router LSA.
*/
public RouterLsa() {
}
/**
* Creates an instance of Router LSA.
*
* @param lsaHeader lsa header instance
*/
public RouterLsa(LsaHeader lsaHeader) {
populateHeader(lsaHeader);
}
/**
* Sets virtual endpoint or not.
*
* @param isVirtualEndPoint true or false
*/
public void setVirtualEndPoint(boolean isVirtualEndPoint) {
this.isVirtualEndPoint = isVirtualEndPoint;
}
/**
* Sets if it is an AS boundary router or not.
*
* @param isAsBoundaryRouter true if AS boundary router else false
*/
public void setAsBoundaryRouter(boolean isAsBoundaryRouter) {
this.isAsBoundaryRouter = isAsBoundaryRouter;
}
/**
* Sets whether it is an ABR or not.
*
* @param isAreaBorderRouter true if ABR else false
*/
public void setAreaBorderRouter(boolean isAreaBorderRouter) {
this.isAreaBorderRouter = isAreaBorderRouter;
}
/**
* Gets number of links.
*
* @return number of links
*/
public int noLink() {
return noLink;
}
/**
* Sets number of links.
*
* @param noLink number of links
*/
public void setNoLink(int noLink) {
this.noLink = noLink;
}
/**
* Adds router link.
*
* @param lsaLink LSA link
*/
public void addRouterLink(OspfLsaLink lsaLink) {
if (!this.routerLinks.contains(lsaLink)) {
this.routerLinks.add(lsaLink);
}
}
/**
* Gets router link.
*
* @return routerLinks LSA link list
*/
public List<OspfLsaLink> routerLink() {
return this.routerLinks;
}
/**
* Reads from channel buffer and populate this.
*
* @param channelBuffer channelBuffer instance.
* @throws OspfParseException might throws exception while parsing buffer
*/
public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {
try {
int veb = channelBuffer.readByte();
int unUsed = channelBuffer.readByte();
//Convert the byte to veb bits
String strVeb = Integer.toBinaryString(veb);
if (strVeb.length() == 3) {
this.setVirtualEndPoint((Integer.parseInt(Character.toString(strVeb.charAt(0))) == 1) ? true : false);
this.setAsBoundaryRouter((Integer.parseInt(Character.toString(strVeb.charAt(1))) == 1) ? true : false);
this.setAreaBorderRouter((Integer.parseInt(Character.toString(strVeb.charAt(2))) == 1) ? true : false);
} else if (strVeb.length() == 2) {
this.setVirtualEndPoint(false);
this.setAsBoundaryRouter((Integer.parseInt(Character.toString(strVeb.charAt(0))) == 1) ? true : false);
this.setAreaBorderRouter((Integer.parseInt(Character.toString(strVeb.charAt(1))) == 1) ? true : false);
} else if (strVeb.length() == 1) {
this.setVirtualEndPoint(false);
this.setAsBoundaryRouter(false);
this.setAreaBorderRouter((Integer.parseInt(Character.toString(strVeb.charAt(0))) == 1) ? true : false);
}
this.setNoLink(channelBuffer.readUnsignedShort());
while (channelBuffer.readableBytes() >= OspfUtil.TWELVE_BYTES) {
OspfLsaLink ospfLsaLink = new OspfLsaLink();
byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
ospfLsaLink.setLinkId(InetAddress.getByAddress(tempByteArray).getHostName());
tempByteArray = new byte[OspfUtil.FOUR_BYTES];
channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
ospfLsaLink.setLinkData(InetAddress.getByAddress(tempByteArray).getHostName());
ospfLsaLink.setLinkType(channelBuffer.readByte());
ospfLsaLink.setTos(channelBuffer.readByte());
ospfLsaLink.setMetric(channelBuffer.readUnsignedShort());
//add the link
this.addRouterLink(ospfLsaLink);
}
} catch (Exception e) {
log.debug("Error::RouterLsa:: {}", e.getMessage());
throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR, OspfErrorType.BAD_MESSAGE);
}
}
/**
* Returns instance as bytes.
*
* @return instance as bytes
* @throws OspfParseException might throws exception while parsing packet
*/
public byte[] asBytes() throws OspfParseException {
byte[] lsaMessage = null;
byte[] lsaHeader = getLsaHeaderAsByteArray();
byte[] lsaBody = getLsaBodyAsByteArray();
lsaMessage = Bytes.concat(lsaHeader, lsaBody);
return lsaMessage;
}
/**
* Gets the LSA body as bytes.
*
* @return LSA body as bytes
*/
public byte[] getLsaBodyAsByteArray() {
List<Byte> bodyLst = new ArrayList<>();
try {
int isVirtualEndPointVal = this.isVirtualEndPoint ? 1 : 0;
int isASBoundaryRouterVal = this.isAsBoundaryRouter ? 1 : 0;
int isAreaBorderRouterVal = this.isAreaBorderRouter ? 1 : 0;
StringBuilder sb = new StringBuilder();
sb.append(Integer.toBinaryString(isVirtualEndPointVal));
sb.append(Integer.toBinaryString(isASBoundaryRouterVal));
sb.append(Integer.toBinaryString(isAreaBorderRouterVal));
//added VEB
bodyLst.add((byte) Integer.parseInt(sb.toString(), 2));
//second byte is 0.
bodyLst.add((byte) 0);
//Number of links
bodyLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.noLink())));
//add each link details
for (OspfLsaLink lsaLink : routerLinks) {
bodyLst.addAll(Bytes.asList(InetAddress.getByName(lsaLink.linkId()).getAddress()));
bodyLst.addAll(Bytes.asList(InetAddress.getByName(lsaLink.linkData()).getAddress()));
bodyLst.add((byte) lsaLink.linkType());
bodyLst.add((byte) lsaLink.tos());
bodyLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(lsaLink.metric())));
}
} catch (Exception e) {
log.debug("Error::getLsrBodyAsByteArray {}", e.getMessage());
return Bytes.toArray(bodyLst);
}
return Bytes.toArray(bodyLst);
}
/**
* Increment the link by 1.
*/
public void incrementLinkNo() {
this.noLink++;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("isVirtualEndPoint", isVirtualEndPoint)
.add("isAsBoundaryRouter", isAsBoundaryRouter)
.add("isAreaBorderRouter", isAreaBorderRouter)
.add("noLink", noLink)
.add("routerLinks", routerLinks)
.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RouterLsa that = (RouterLsa) o;
return Objects.equal(isVirtualEndPoint, that.isVirtualEndPoint) &&
Objects.equal(isAsBoundaryRouter, that.isAsBoundaryRouter) &&
Objects.equal(isAreaBorderRouter, that.isAreaBorderRouter) &&
Objects.equal(noLink, that.noLink) &&
Objects.equal(routerLinks, that.routerLinks);
}
@Override
public int hashCode() {
return Objects.hashCode(isVirtualEndPoint, isAsBoundaryRouter, isAreaBorderRouter,
noLink, routerLinks);
}
}