[Emu] [ONOS-2601] Implement BGP Update protocol message and parse all basic path attributes.
Change-Id: I85f912eeebacf46d699fdcf5549e06bae702823e
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java
new file mode 100644
index 0000000..90e94e8
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2015 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.bgpio.types;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Implementation of As4Path BGP Path Attribute.
+ */
+public class As4Path implements BGPValueType {
+ private static final Logger log = LoggerFactory.getLogger(AsPath.class);
+ public static final byte AS4PATH_TYPE = 17;
+ public static final byte ASNUM_SIZE = 4;
+ public static final int TYPE_AND_LEN_AS_SHORT = 4;
+ public static final int TYPE_AND_LEN_AS_BYTE = 3;
+
+ private List<Integer> as4pathSet;
+ private List<Integer> as4pathSeq;
+
+ /**
+ * Initialize fields.
+ */
+ public As4Path() {
+ this.as4pathSeq = null;
+ this.as4pathSet = null;
+ }
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param as4pathSet AS4path Set
+ * @param as4pathSeq AS4path Sequence
+ */
+ public As4Path(List<Integer> as4pathSet, List<Integer> as4pathSeq) {
+ this.as4pathSeq = as4pathSeq;
+ this.as4pathSet = as4pathSet;
+ }
+
+ /**
+ * Reads from the channel buffer and parses As4Path.
+ *
+ * @param cb ChannelBuffer
+ * @return object of As4Path
+ * @throws BGPParseException while parsing As4Path
+ */
+ public static As4Path read(ChannelBuffer cb) throws BGPParseException {
+ List<Integer> as4pathSet = new ArrayList<>();
+ List<Integer> as4pathSeq = new ArrayList<>();
+ ChannelBuffer tempCb = cb.copy();
+ Validation validation = Validation.parseAttributeHeader(cb);
+
+ if (cb.readableBytes() < validation.getLength()) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+ validation.getLength());
+ }
+ //if fourth bit is set length is read as short otherwise as byte , len includes type, length and value
+ int len = validation.isShort() ? validation.getLength() + TYPE_AND_LEN_AS_SHORT : validation
+ .getLength() + TYPE_AND_LEN_AS_BYTE;
+ ChannelBuffer data = tempCb.readBytes(len);
+ if (validation.getFirstBit() && !validation.getSecondBit() && validation.getThirdBit()) {
+ throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data);
+ }
+
+ ChannelBuffer tempBuf = cb.readBytes(validation.getLength());
+ while (tempBuf.readableBytes() > 0) {
+ byte pathSegType = tempBuf.readByte();
+ //no of ASes
+ byte pathSegLen = tempBuf.readByte();
+ //length = no of Ases * ASnum size (4 bytes)
+ int length = pathSegLen * ASNUM_SIZE;
+ if (tempBuf.readableBytes() < length) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR,
+ BGPErrorType.ATTRIBUTE_LENGTH_ERROR, length);
+ }
+ ChannelBuffer aspathBuf = tempBuf.readBytes(length);
+ while (aspathBuf.readableBytes() > 0) {
+ int asNum;
+ asNum = aspathBuf.readInt();
+ switch (pathSegType) {
+ case AsPath.ASPATH_SET_TYPE:
+ as4pathSet.add(asNum);
+ break;
+ case AsPath.ASPATH_SEQ_TYPE:
+ as4pathSeq.add(asNum);
+ break;
+ default: log.debug("Other type Not Supported:" + pathSegType);
+ }
+ }
+ }
+ return new As4Path(as4pathSet, as4pathSeq);
+ }
+
+ @Override
+ public short getType() {
+ return AS4PATH_TYPE;
+ }
+
+ /**
+ * Returns list of ASNum in AS4path Sequence.
+ *
+ * @return list of ASNum in AS4path Sequence
+ */
+ public List<Integer> as4PathSEQ() {
+ return this.as4pathSeq;
+ }
+
+ /**
+ * Returns list of ASNum in AS4path Set.
+ *
+ * @return list of ASNum in AS4path Set
+ */
+ public List<Integer> as4PathSET() {
+ return this.as4pathSet;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(as4pathSet, as4pathSeq);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof As4Path) {
+ As4Path other = (As4Path) obj;
+ return Objects.equals(as4pathSet, other.as4pathSet) && Objects.equals(as4pathSeq, other.as4pathSeq);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues()
+ .add("as4pathSet", as4pathSet)
+ .add("as4pathSeq", as4pathSeq)
+ .toString();
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ //Not required to Implement as of now
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java
new file mode 100644
index 0000000..100e14d
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2015 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.bgpio.types;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Implementation of AsPath mandatory BGP Path Attribute.
+ */
+public class AsPath implements BGPValueType {
+ /**
+ * Enum to provide AS types.
+ */
+ public enum ASTYPE {
+ AS_SET(1), AS_SEQUENCE(2), AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4);
+ int value;
+
+ /**
+ * Assign val with the value as the AS type.
+ *
+ * @param val AS type
+ */
+ ASTYPE(int val) {
+ value = val;
+ }
+
+ /**
+ * Returns value of AS type.
+ *
+ * @return AS type
+ */
+ public byte getType() {
+ return (byte) value;
+ }
+ }
+
+ private static final Logger log = LoggerFactory.getLogger(AsPath.class);
+ public static final byte ASPATH_TYPE = 2;
+ public static final byte ASPATH_SET_TYPE = 1;
+ public static final byte ASPATH_SEQ_TYPE = 2;
+ public static final byte ASNUM_SIZE = 2;
+ public static final int TYPE_AND_LEN_AS_SHORT = 4;
+ public static final int TYPE_AND_LEN_AS_BYTE = 3;
+
+ private boolean isAsPath = false;
+ private List<Short> aspathSet;
+ private List<Short> aspathSeq;
+
+ /**
+ * Initialize Fields.
+ */
+ public AsPath() {
+ this.aspathSeq = null;
+ this.aspathSet = null;
+ }
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param aspathSet ASpath Set type
+ * @param aspathSeq ASpath Sequence type
+ */
+ public AsPath(List<Short> aspathSet, List<Short> aspathSeq) {
+ this.aspathSeq = aspathSeq;
+ this.aspathSet = aspathSet;
+ this.isAsPath = true;
+ }
+
+ /**
+ * Reads from the channel buffer and parses AsPath.
+ *
+ * @param cb ChannelBuffer
+ * @return object of AsPath
+ * @throws BGPParseException while parsing AsPath
+ */
+ public static AsPath read(ChannelBuffer cb) throws BGPParseException {
+ List<Short> aspathSet = new ArrayList<>();
+ List<Short> aspathSeq = new ArrayList<>();
+ ChannelBuffer tempCb = cb.copy();
+ Validation validation = Validation.parseAttributeHeader(cb);
+
+ if (cb.readableBytes() < validation.getLength()) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+ validation.getLength());
+ }
+ //if fourth bit is set, length is read as short otherwise as byte , len includes type, length and value
+ int len = validation.isShort() ? validation.getLength() + TYPE_AND_LEN_AS_SHORT : validation
+ .getLength() + TYPE_AND_LEN_AS_BYTE;
+ ChannelBuffer data = tempCb.readBytes(len);
+ if (validation.getFirstBit() && !validation.getSecondBit() && validation.getThirdBit()) {
+ throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data);
+ }
+
+ ChannelBuffer tempBuf = cb.readBytes(validation.getLength());
+ while (tempBuf.readableBytes() > 0) {
+ byte pathSegType = tempBuf.readByte();
+ //no of ASes
+ byte pathSegLen = tempBuf.readByte();
+ int length = pathSegLen * ASNUM_SIZE;
+ if (tempBuf.readableBytes() < length) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR,
+ BGPErrorType.ATTRIBUTE_LENGTH_ERROR, length);
+ }
+ ChannelBuffer aspathBuf = tempBuf.readBytes(length);
+ while (aspathBuf.readableBytes() > 0) {
+ short asNum;
+ asNum = aspathBuf.readShort();
+ switch (pathSegType) {
+ case ASPATH_SET_TYPE:
+ aspathSet.add(asNum);
+ break;
+ case ASPATH_SEQ_TYPE:
+ aspathSeq.add(asNum);
+ break;
+ default: log.debug("Other type Not Supported:" + pathSegType);
+ }
+ }
+ }
+ return new AsPath(aspathSet, aspathSeq);
+ }
+
+ @Override
+ public short getType() {
+ return ASPATH_TYPE;
+ }
+
+ /**
+ * Returns whether ASpath path attribute is present.
+ *
+ * @return whether ASpath path attribute is present
+ */
+ public boolean isaspathSet() {
+ return this.isAsPath;
+ }
+
+ /**
+ * Returns list of ASNum in ASpath Sequence.
+ *
+ * @return list of ASNum in ASpath Sequence
+ */
+ public List<Short> asPathSeq() {
+ return this.aspathSeq;
+ }
+
+ /**
+ * Returns list of ASNum in ASpath SET.
+ *
+ * @return list of ASNum in ASpath SET
+ */
+ public List<Short> asPathSet() {
+ return this.aspathSet;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(aspathSet, aspathSeq);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof AsPath) {
+ AsPath other = (AsPath) obj;
+ return Objects.equals(aspathSet, other.aspathSet) && Objects.equals(aspathSeq, other.aspathSeq);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues()
+ .add("aspathSet", aspathSet)
+ .add("aspathSeq", aspathSeq)
+ .toString();
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ //Not required to Implement as of now
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LocalPref.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LocalPref.java
new file mode 100644
index 0000000..048d81e
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LocalPref.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2015 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.bgpio.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides implementation of LocalPref BGP Path Attribute.
+ */
+public class LocalPref implements BGPValueType {
+
+ private static final Logger log = LoggerFactory.getLogger(LocalPref.class);
+ public static final byte LOCAL_PREF_TYPE = 5;
+ public static final int TYPE_AND_LEN_AS_SHORT = 4;
+ public static final int TYPE_AND_LEN_AS_BYTE = 3;
+ public static final byte LOCAL_PREF_MAX_LEN = 4;
+
+ private int localPref;
+
+ /**
+ * Constructor to initialize LocalPref.
+ *
+ * @param localPref local preference
+ */
+ public LocalPref(int localPref) {
+ this.localPref = localPref;
+ }
+
+ /**
+ * Returns local preference value.
+ *
+ * @return local preference value
+ */
+ public int localPref() {
+ return this.localPref;
+ }
+
+ /**
+ * Reads the channel buffer and returns object of LocalPref.
+ *
+ * @param cb channelBuffer
+ * @return object of LocalPref
+ * @throws BGPParseException while parsing localPref attribute
+ */
+ public static LocalPref read(ChannelBuffer cb) throws BGPParseException {
+ int localPref;
+ ChannelBuffer tempCb = cb.copy();
+ Validation parseFlags = Validation.parseAttributeHeader(cb);
+ if ((parseFlags.getLength() > LOCAL_PREF_MAX_LEN) || cb.readableBytes() < parseFlags.getLength()) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+ parseFlags.getLength());
+ }
+
+ int len = parseFlags.isShort() ? parseFlags.getLength() + TYPE_AND_LEN_AS_SHORT : parseFlags.getLength()
+ + TYPE_AND_LEN_AS_BYTE;
+ ChannelBuffer data = tempCb.readBytes(len);
+ if (parseFlags.getFirstBit()) {
+ throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data);
+ }
+
+ localPref = cb.readInt();
+ return new LocalPref(localPref);
+ }
+
+ @Override
+ public short getType() {
+ return LOCAL_PREF_TYPE;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(localPref);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof LocalPref) {
+ LocalPref other = (LocalPref) obj;
+ return Objects.equals(localPref, other.localPref);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("localPref", localPref)
+ .toString();
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ //Not to implement as of now
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Med.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Med.java
new file mode 100644
index 0000000..49e1fc5
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Med.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2015 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.bgpio.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Implementation of Med BGP Path Attribute.
+ */
+public class Med implements BGPValueType {
+ private static final Logger log = LoggerFactory.getLogger(Med.class);
+ public static final byte MED_TYPE = 4;
+ public static final int TYPE_AND_LEN_AS_SHORT = 4;
+ public static final int TYPE_AND_LEN_AS_BYTE = 3;
+ public static final byte MED_MAX_LEN = 4;
+
+ private int med;
+
+ /**
+ * Constructor to initialize med.
+ *
+ * @param med MULTI_EXIT_DISC value
+ */
+ public Med(int med) {
+ this.med = med;
+ }
+
+ /**
+ * Returns Med value.
+ *
+ * @return Med value
+ */
+ public int med() {
+ return this.med;
+ }
+
+ /**
+ * Reads the channel buffer and returns object of Med.
+ *
+ * @param cb ChannelBuffer
+ * @return object of Med
+ * @throws BGPParseException while parsing Med path attribute
+ */
+ public static Med read(ChannelBuffer cb) throws BGPParseException {
+ int med;
+ ChannelBuffer tempCb = cb.copy();
+ Validation parseFlags = Validation.parseAttributeHeader(cb);
+
+ if ((parseFlags.getLength() > MED_MAX_LEN) || cb.readableBytes() < parseFlags.getLength()) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+ parseFlags.getLength());
+ }
+ int len = parseFlags.isShort() ? parseFlags.getLength() + TYPE_AND_LEN_AS_SHORT : parseFlags
+ .getLength() + TYPE_AND_LEN_AS_BYTE;
+ ChannelBuffer data = tempCb.readBytes(len);
+ if (!parseFlags.getFirstBit() && parseFlags.getSecondBit() && parseFlags.getThirdBit()) {
+ throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data);
+ }
+
+ med = cb.readInt();
+ return new Med(med);
+ }
+
+ @Override
+ public short getType() {
+ return MED_TYPE;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(med);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof Med) {
+ Med other = (Med) obj;
+ return Objects.equals(med, other.med);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("med", med)
+ .toString();
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ //Not to implement as of now
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/NextHop.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/NextHop.java
new file mode 100644
index 0000000..353ec3d
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/NextHop.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2015 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.bgpio.types;
+
+import java.net.InetAddress;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+/**
+ * Implementation of NextHop BGP Path Attribute.
+ */
+public class NextHop implements BGPValueType {
+ private static final Logger log = LoggerFactory.getLogger(NextHop.class);
+ public static final byte NEXTHOP_TYPE = 3;
+ public static final int TYPE_AND_LEN_AS_SHORT = 4;
+ public static final int TYPE_AND_LEN_AS_BYTE = 3;
+
+ private boolean isNextHop = false;
+ private Ip4Address nextHop;
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param nextHop nextHop address
+ */
+ public NextHop(Ip4Address nextHop) {
+ this.nextHop = Preconditions.checkNotNull(nextHop);
+ this.isNextHop = true;
+ }
+
+ /**
+ * Returns whether next hop is present.
+ *
+ * @return whether next hop is present
+ */
+ public boolean isNextHopSet() {
+ return this.isNextHop;
+ }
+
+ /**
+ * Reads from ChannelBuffer and parses NextHop.
+ *
+ * @param cb ChannelBuffer
+ * @return object of NextHop
+ * @throws BGPParseException while parsing nexthop attribute
+ */
+ public static NextHop read(ChannelBuffer cb) throws BGPParseException {
+ Ip4Address nextHop;
+ ChannelBuffer tempCb = cb.copy();
+ Validation parseFlags = Validation.parseAttributeHeader(cb);
+
+ if (cb.readableBytes() < parseFlags.getLength()) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+ parseFlags.getLength());
+ }
+ int len = parseFlags.isShort() ? parseFlags.getLength() + TYPE_AND_LEN_AS_SHORT : parseFlags
+ .getLength() + TYPE_AND_LEN_AS_BYTE;
+ ChannelBuffer data = tempCb.readBytes(len);
+ if (parseFlags.getFirstBit() && !parseFlags.getSecondBit() && parseFlags.getThirdBit()) {
+ throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data);
+ }
+
+ //TODO: use Validation.toInetAddress once Validation is merged
+ InetAddress ipAddress = (InetAddress) cb.readBytes(parseFlags.getLength());
+ if (ipAddress.isMulticastAddress()) {
+ throw new BGPParseException("Multicast address is not supported");
+ }
+
+ nextHop = Ip4Address.valueOf(ipAddress);
+ return new NextHop(nextHop);
+ }
+
+ /**
+ * Return nexthop address.
+ *
+ * @return nexthop address
+ */
+ public Ip4Address nextHop() {
+ return nextHop;
+ }
+
+ @Override
+ public short getType() {
+ return NEXTHOP_TYPE;
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ //Not required to be implemented now
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(nextHop);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof NextHop) {
+ NextHop other = (NextHop) obj;
+ return Objects.equals(nextHop, other.nextHop);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("nextHop", nextHop)
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Origin.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Origin.java
new file mode 100644
index 0000000..3b2070d
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Origin.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2015 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.bgpio.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Implementation of mandatory BGP Origin path attribute.
+ */
+public class Origin implements BGPValueType {
+ private static final Logger log = LoggerFactory.getLogger(Origin.class);
+
+ /**
+ * Enum to provide ORIGIN types.
+ */
+ public enum ORIGINTYPE {
+ IGP(0), EGP(1), INCOMPLETE(2);
+ int value;
+ /**
+ * Assign val with the value as the ORIGIN type.
+ *
+ * @param val ORIGIN type
+ */
+ ORIGINTYPE(int val) {
+ value = val;
+ }
+
+ /**
+ * Returns value of ORIGIN type.
+ *
+ * @return ORIGIN type
+ */
+ public byte getType() {
+ return (byte) value;
+ }
+ }
+
+ public static final byte ORIGIN_TYPE = 1;
+ public static final byte ORIGIN_VALUE_LEN = 1;
+ public static final int TYPE_AND_LEN_AS_SHORT = 4;
+ public static final int TYPE_AND_LEN_AS_BYTE = 3;
+
+ private boolean isOrigin = false;
+ private byte origin;
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param origin origin value
+ */
+ public Origin(byte origin) {
+ this.origin = origin;
+ this.isOrigin = true;
+ }
+
+ /**
+ * Returns true if origin attribute is present otherwise false.
+ *
+ * @return whether origin is present or not
+ */
+ public boolean isOriginSet() {
+ return this.isOrigin;
+ }
+
+ /**
+ * Returns type of Origin in Enum values.
+ *
+ * @return type of Origin in Enum values
+ */
+ public ORIGINTYPE origin() {
+ if (this.origin == 0) {
+ return ORIGINTYPE.IGP;
+ } else if (this.origin == 1) {
+ return ORIGINTYPE.EGP;
+ } else {
+ return ORIGINTYPE.INCOMPLETE;
+ }
+ }
+
+ /**
+ * Reads from ChannelBuffer and parses Origin.
+ *
+ * @param cb ChannelBuffer
+ * @return object of Origin
+ * @throws BGPParseException while parsing Origin path attribute
+ */
+ public static Origin read(ChannelBuffer cb) throws BGPParseException {
+ ChannelBuffer tempCb = cb.copy();
+ Validation parseFlags = Validation.parseAttributeHeader(cb);
+
+ int len = parseFlags.isShort() ? parseFlags.getLength() + TYPE_AND_LEN_AS_SHORT : parseFlags
+ .getLength() + TYPE_AND_LEN_AS_BYTE;
+ ChannelBuffer data = tempCb.readBytes(len);
+ if ((parseFlags.getLength() > ORIGIN_VALUE_LEN) || (cb.readableBytes() < parseFlags.getLength())) {
+ Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+ parseFlags.getLength());
+ }
+ if (parseFlags.getFirstBit() && !parseFlags.getSecondBit() && parseFlags.getThirdBit()) {
+ throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data);
+ }
+
+ byte originValue;
+ originValue = cb.readByte();
+ if ((originValue != ORIGINTYPE.INCOMPLETE.value) || (originValue != ORIGINTYPE.IGP.value) ||
+ (originValue != ORIGINTYPE.EGP.value)) {
+ throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.INVALID_ORIGIN_ATTRIBUTE, data);
+ }
+ return new Origin(originValue);
+ }
+
+ @Override
+ public short getType() {
+ return ORIGIN_TYPE;
+ }
+
+ @Override
+ public int write(ChannelBuffer cb) {
+ //Not required to Implement as of now
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(origin);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof Origin) {
+ Origin other = (Origin) obj;
+ return Objects.equals(origin, other.origin);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("origin", origin)
+ .toString();
+ }
+}
\ No newline at end of file