From e9bb60be43af477f17b30ee1f2ba205565b7fa15 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Mon, 19 Oct 2015 10:14:31 -0700 Subject: Updated onos src tree to commit id 1e60f97ae50c05b94fcb6a10520738bfb5efdfd1 --- .../onosproject/bgp/controller/BGPController.java | 28 + .../org/onosproject/bgp/controller/BGPPeer.java | 161 ++++++ .../bgpio/protocol/BGPKeepaliveMsg.java | 10 - .../org/onosproject/bgpio/protocol/BGPLSNlri.java | 54 ++ .../org/onosproject/bgpio/protocol/BGPMessage.java | 21 - .../onosproject/bgpio/protocol/BGPNodeLSNlri.java | 30 + .../bgpio/protocol/BGPNotificationMsg.java | 87 +++ .../org/onosproject/bgpio/protocol/BGPOpenMsg.java | 40 +- .../bgpio/protocol/BGPPrefixLSNlri.java | 40 ++ .../onosproject/bgpio/protocol/IGPRouterID.java | 44 +- .../org/onosproject/bgpio/protocol/NlriType.java | 45 ++ .../protocol/link_state/BGPNodeLSIdentifier.java | 113 ++++ .../protocol/link_state/BGPNodeLSNlriVer4.java | 212 ++++++++ .../link_state/BGPPrefixIPv4LSNlriVer4.java | 205 +++++++ .../bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java | 15 - .../protocol/ver4/BGPNotificationMsgVer4.java | 266 +++++++++ .../bgpio/protocol/ver4/BGPOpenMsgVer4.java | 136 +++-- .../bgpio/types/FourOctetAsNumCapabilityTlv.java | 114 ++++ .../types/MultiProtocolExtnCapabilityTlv.java | 160 ++++++ .../bgpio/types/RouteDistinguisher.java | 62 +++ .../bgpio/types/attr/BgpAttrRouterIdV4.java | 124 +++++ .../bgpio/types/attr/BgpAttrRouterIdV6.java | 124 +++++ .../bgpio/types/attr/BgpLinkAttrName.java | 119 ++++ .../bgpio/types/attr/BgpPrefixAttrIGPFlags.java | 180 ++++++ .../bgpio/types/attr/BgpPrefixAttrRouteTag.java | 125 +++++ .../java/org/onosproject/bgpio/util/Constants.java | 37 ++ .../bgp/controller/impl/BGPChannelHandler.java | 601 ++++++++++++++++++++- .../bgp/controller/impl/BGPControllerImpl.java | 179 +++++- .../bgp/controller/impl/BGPKeepAliveTimer.java | 72 +++ .../bgp/controller/impl/BGPPacketStatsImpl.java | 12 +- .../bgp/controller/impl/BGPPeerImpl.java | 191 +++++++ .../bgp/controller/impl/BGPSessionInfo.java | 149 +++++ 32 files changed, 3623 insertions(+), 133 deletions(-) create mode 100755 framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNotificationMsg.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/NlriType.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIGPFlags.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java create mode 100755 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java create mode 100755 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java create mode 100755 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java (limited to 'framework/src/onos/bgp') diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java index 6d758122..49432aab 100755 --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java @@ -24,6 +24,21 @@ import org.onosproject.bgpio.protocol.BGPMessage; */ public interface BGPController { + /** + * Returns list of bgp peers connected to this BGP controller. + * + * @return Iterable of BGPPeer elements + */ + Iterable getPeers(); + + /** + * Returns the actual bgp peer for the given ip address. + * + * @param bgpId the id of the bgp peer to fetch + * @return the interface to this bgp peer + */ + BGPPeer getPeer(BGPId bgpId); + /** * Send a message to a particular bgp peer. * @@ -40,10 +55,23 @@ public interface BGPController { */ void processBGPPacket(BGPId bgpId, BGPMessage msg); + /** + * Close all connected BGP peers. + * + */ + void closeConnectedPeers(); + /** * Get the BGPConfig class to the caller. * * @return configuration object */ BGPCfg getConfig(); + + /** + * Get the BGP connected peers to this controller. + * + * @return the integer number + */ + int getBGPConnNumber(); } \ No newline at end of file diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java new file mode 100755 index 00000000..1b022c76 --- /dev/null +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java @@ -0,0 +1,161 @@ +/* + * 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.bgp.controller; +import java.util.List; +import org.jboss.netty.channel.Channel; +import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.protocol.BGPVersion; + +/** + * Represents the peer side of an bgp peer. + * + */ +public interface BGPPeer { + + /** + * Sets the BGP version for this bgp peer. + * + * @param bgpVersion the version to set. + */ + void setBgpPeerVersion(BGPVersion bgpVersion); + + /** + * Gets the BGP version for this bgp peer. + * + * @return bgp identifier. + */ + int getBgpPeerIdentifier(); + + /** + * Sets the associated Netty channel for this bgp peer. + * + * @param channel the Netty channel + */ + void setChannel(Channel channel); + + /** + * Gets the associated Netty channel handler for this bgp peer. + * + * @return Channel channel connected. + */ + Channel getChannel(); + + /** + * Sets the AS Number for this bgp peer. + * + * @param peerASNum the autonomous system number value to set. + */ + void setBgpPeerASNum(short peerASNum); + + /** + * Sets the hold time for this bgp peer. + * + * @param peerHoldTime the hold timer value to set. + */ + void setBgpPeerHoldTime(short peerHoldTime); + + /** + * Sets the peer identifier value. + * + * @param peerIdentifier the bgp peer identifier value. + */ + void setBgpPeerIdentifier(int peerIdentifier); + + /** + * Sets whether the bgp peer is connected. + * + * @param connected whether the bgp peer is connected + */ + void setConnected(boolean connected); + + /** + * Initialises the behaviour. + * + * @param bgpId id of bgp peer + * @param bgpVersion BGP version + * @param pktStats packet statistics + */ + void init(BGPId bgpId, BGPVersion bgpVersion, BGPPacketStats pktStats); + + /** + * Checks whether the handshake is complete. + * + * @return true is finished, false if not. + */ + boolean isHandshakeComplete(); + + /** + * Writes the message to the peer. + * + * @param msg the message to write + */ + void sendMessage(BGPMessage msg); + + /** + * Writes the BGPMessage list to the peer. + * + * @param msgs the messages to be written + */ + void sendMessage(List msgs); + + /** + * Gets a string version of the ID for this bgp peer. + * + * @return string version of the ID + */ + String getStringId(); + + /** + * Gets the ipAddress of the peer. + * + * @return the peer bgpId in IPAddress format + */ + BGPId getBGPId(); + + /** + * Checks if the bgp peer is still connected. + * + * @return whether the bgp peer is still connected + */ + boolean isConnected(); + + /** + * Disconnects the bgp peer by closing the TCP connection. Results in a call to the channel handler's + * channelDisconnected method for cleanup + */ + void disconnectPeer(); + + /** + * Identifies the channel used to communicate with the bgp peer. + * + * @return string representation of the connection to the peer + */ + String channelId(); + + /** + * Gets the negotiated hold time. + * + * @return the negotiated hold time + */ + int getNegotiatedHoldTime(); + + /** + * Sets negotiated hold time for the peer. + * + * @param negotiatedHoldTime negotiated hold time + */ + void setNegotiatedHoldTime(short negotiatedHoldTime); +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsg.java index c8aef36e..ae773889 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsg.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsg.java @@ -39,20 +39,10 @@ public interface BGPKeepaliveMsg extends BGPMessage { * Builder interface with get and set functions to build Keepalive message. */ interface Builder extends BGPMessage.Builder { - @Override BGPKeepaliveMsg build(); - @Override - BGPVersion getVersion(); - - @Override - BGPType getType(); - @Override Builder setHeader(BGPHeader bgpMsgHeader); - - @Override - BGPHeader getHeader(); } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java new file mode 100644 index 00000000..572e2aeb --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java @@ -0,0 +1,54 @@ +/* + * 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.protocol; + +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.protocol.link_state.BGPNodeLSNlriVer4.PROTOCOLTYPE; +import org.onosproject.bgpio.types.RouteDistinguisher; + +/** + * Abstraction of an entity providing BGP-LS NLRI. + */ +public interface BGPLSNlri { + /** + * Returns NlriType of BGP-LS NLRI. + * + * @return NlriType of BGP-LS NLRI + */ + NlriType getNlriType(); + + /** + * Returns Identifier in Nlri. + * + * @return Identifier in Nlri + */ + long getIdentifier(); + + /** + * Returns Protocol Id in Nlri. + * + * @return Protocol Id in Nlri + * @throws BGPParseException while getting protocol ID + */ + PROTOCOLTYPE getProtocolId() throws BGPParseException; + + /** + * Returns Route distinguisher in Nlri. + * + * @return Route distinguisher in Nlri + */ + RouteDistinguisher getRouteDistinguisher(); +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessage.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessage.java index a5d8154f..309ef435 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessage.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessage.java @@ -60,27 +60,6 @@ public interface BGPMessage extends Writeable { */ BGPMessage build() throws BGPParseException; - /** - * Returns BGP Version of BGP Message. - * - * @return BGP Version of BGP Message - */ - BGPVersion getVersion(); - - /** - * Returns BGP Type of BGP Message. - * - * @return BGP Type of BGP Message - */ - BGPType getType(); - - /** - * Returns BGP Header of BGP Message. - * - * @return BGP Header of BGP Message - */ - BGPHeader getHeader(); - /** * Sets BgpHeader and return its builder. * diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java new file mode 100644 index 00000000..fd5b8056 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java @@ -0,0 +1,30 @@ +/* + * 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.protocol; + +import org.onosproject.bgpio.protocol.link_state.BGPNodeLSIdentifier; + +/** + * Abstraction of an entity providing BGP-LS Node NLRI. + */ +public interface BGPNodeLSNlri extends BGPLSNlri { + /** + * Returns local node descriptors. + * + * @return local node descriptors + */ + BGPNodeLSIdentifier getLocalNodeDescriptors(); +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNotificationMsg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNotificationMsg.java new file mode 100644 index 00000000..56540dd3 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNotificationMsg.java @@ -0,0 +1,87 @@ +/* + * 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.protocol; + +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.types.BGPHeader; + +/** + * Abstraction of an entity providing BGP Notification Message. + */ +public interface BGPNotificationMsg extends BGPMessage { + /** + * Returns errorCode in Notification message. + * + * @return errorCode in Notification message + */ + byte getErrorCode(); + + /** + * Returns error SubCode in Notification message. + * + * @return error SubCode in Notification message + */ + byte getErrorSubCode(); + + /** + * Returns error data in Notification message. + * + * @return error data in Notification message + */ + byte[] getData(); + + /** + * Builder interface with get and set functions to build Notification + * message. + */ + public interface Builder extends BGPMessage.Builder { + + @Override + BGPNotificationMsg build() throws BGPParseException; + + /** + * Sets notification message header and returns its builder. + * + * @param header of notification message + * @return Builder by setting notification message header + */ + Builder setNotificationMsgHeader(BGPHeader header); + + /** + * Sets errorCode in notification message and return its builder. + * + * @param errorCode in notification message + * @return builder by setting ErrorCode in notification message + */ + Builder setErrorCode(byte errorCode); + + /** + * Sets error SubCode in notification message and return its builder. + * + * @param errorSubCode in notification Message + * @return builder by setting ErrorSubCode in notification Message + */ + Builder setErrorSubCode(byte errorSubCode); + + /** + * Sets error data in notification message and return its builder. + * + * @param data in notification message + * @return builder by setting Data in notification message + */ + Builder setData(byte[] data); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPOpenMsg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPOpenMsg.java index c41e5eb6..a8c242b4 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPOpenMsg.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPOpenMsg.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.onosproject.bgpio.protocol; import java.util.LinkedList; @@ -72,15 +71,6 @@ public interface BGPOpenMsg extends BGPMessage { @Override BGPOpenMsg build() throws BGPParseException; - @Override - BGPHeader getHeader(); - - @Override - BGPVersion getVersion(); - - @Override - BGPType getType(); - /** * Returns hold time of Open Message. * @@ -91,8 +81,7 @@ public interface BGPOpenMsg extends BGPMessage { /** * Sets hold time in Open Message and return its builder. * - * @param holdtime - * hold timer value in open message + * @param holdtime hold timer value in open message * @return builder by setting hold time */ Builder setHoldTime(short holdtime); @@ -107,8 +96,7 @@ public interface BGPOpenMsg extends BGPMessage { /** * Sets AS number in Open Message and return its builder. * - * @param asNumber - * as number in open message + * @param asNumber as number in open message * @return builder by setting asNumber */ Builder setAsNumber(short asNumber); @@ -123,8 +111,7 @@ public interface BGPOpenMsg extends BGPMessage { /** * Sets BGP Identifier in Open Message and return its builder. * - * @param bgpId - * BGP Identifier in open message + * @param bgpId BGP Identifier in open message * @return builder by setting BGP Identifier */ Builder setBgpId(int bgpId); @@ -139,12 +126,29 @@ public interface BGPOpenMsg extends BGPMessage { /** * Sets capabilities in Open Message and return its builder. * - * @param capabilityTlv - * capabilities in open message + * @param capabilityTlv capabilities in open message * @return builder by setting capabilities */ Builder setCapabilityTlv(LinkedList capabilityTlv); + /** + * Sets isLargeAsCapabilityTlvSet and return its builder. + * + * @param isLargeAsCapabilitySet + * boolean value to know whether large AS capability is set or not + * @return builder by setting capabilities + */ + Builder setLargeAsCapabilityTlv(boolean isLargeAsCapabilitySet); + + /** + * Sets isLsCapabilityTlvSet and return its builder. + * + * @param isLsCapabilitySet + * boolean value to know whether LS capability is set or not + * @return builder by setting capabilities + */ + Builder setLsCapabilityTlv(boolean isLsCapabilitySet); + @Override Builder setHeader(BGPHeader bgpMsgHeader); } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java new file mode 100644 index 00000000..7e849f48 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java @@ -0,0 +1,40 @@ +/* + * 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.protocol; + +import java.util.LinkedList; + +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.protocol.link_state.NodeDescriptors; + +/** + * Abstraction of an entity providing BGP-LS Prefix NLRI. + */ +public interface BGPPrefixLSNlri extends BGPLSNlri { + /** + * Returns local node descriptors. + * + * @return local node descriptors + */ + NodeDescriptors getLocalNodeDescriptors(); + + /** + * Returns list of Prefix descriptor. + * + * @return list of Prefix descriptor + */ + LinkedList getPrefixdescriptor(); +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/IGPRouterID.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/IGPRouterID.java index 377d12b7..0e531d64 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/IGPRouterID.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/IGPRouterID.java @@ -1,23 +1,23 @@ -/* - * 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.protocol; - -/** - * Provides Abstraction of IGP RouterID TLV. - */ -public interface IGPRouterID { +/* + * 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.protocol; + +/** + * Provides Abstraction of IGP RouterID TLV. + */ +public interface IGPRouterID { } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/NlriType.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/NlriType.java new file mode 100644 index 00000000..535ba71d --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/NlriType.java @@ -0,0 +1,45 @@ +/* + * 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.protocol; + +/** + * Enum to Provide the Different BGP-LS NLRI types. + */ +public enum NlriType { + + NODE(1), LINK(2), PREFIX_IPV4(3), PREFIX_IPV6(4); + + int value; + + /** + * Assign value with the value as the LINK-STATE NLRI type. + * + * @param value LINK-STATE NLRI type + */ + NlriType(int value) { + this.value = value; + } + + /** + * Returns value as LINK-STATE NLRI type. + * + * @return value LINK-STATE NLRI type + */ + public byte getType() { + return (byte) value; + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java new file mode 100644 index 00000000..cd2422a7 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java @@ -0,0 +1,113 @@ +/* + * 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.protocol.link_state; + +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.util.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Node Identifier which includes local node descriptor/remote node descriptors. + */ +public class BGPNodeLSIdentifier { + + protected static final Logger log = LoggerFactory.getLogger(BGPNodeLSIdentifier.class); + private NodeDescriptors nodeDescriptors; + + /** + * Resets fields. + */ + public BGPNodeLSIdentifier() { + this.nodeDescriptors = null; + } + + /** + * Constructor to initialize fields. + * + * @param nodeDescriptors local/remote node descriptor + */ + public BGPNodeLSIdentifier(NodeDescriptors nodeDescriptors) { + this.nodeDescriptors = nodeDescriptors; + } + + /** + * Parse local node descriptors. + * + * @param cb ChannelBuffer + * @param protocolId protocol identifier + * @return object of this BGPNodeLSIdentifier + * @throws BGPParseException while parsing local node descriptors + */ + public static BGPNodeLSIdentifier parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) + throws BGPParseException { + ChannelBuffer tempBuf = cb; + short type = cb.readShort(); + short length = cb.readShort(); + if (cb.readableBytes() < length) { + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, + tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN)); + } + NodeDescriptors nodeDescriptors = new NodeDescriptors(); + ChannelBuffer tempCb = cb.readBytes(length); + + if (type == NodeDescriptors.LOCAL_NODE_DES_TYPE) { + nodeDescriptors = NodeDescriptors.read(tempCb, length, type, protocolId); + } else { + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); + } + return new BGPNodeLSIdentifier(nodeDescriptors); + } + + /** + * Returns node descriptors. + * + * @return node descriptors + */ + public NodeDescriptors getNodedescriptors() { + return this.nodeDescriptors; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof BGPNodeLSIdentifier) { + BGPNodeLSIdentifier other = (BGPNodeLSIdentifier) obj; + return Objects.equals(nodeDescriptors, other.nodeDescriptors); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(nodeDescriptors); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("NodeDescriptors", nodeDescriptors) + .toString(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java new file mode 100644 index 00000000..04780d82 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java @@ -0,0 +1,212 @@ +/* + * 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.protocol.link_state; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.protocol.BGPNodeLSNlri; +import org.onosproject.bgpio.protocol.NlriType; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.RouteDistinguisher; +import org.onosproject.bgpio.util.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Node LS NLRI. + */ +public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { + + /* + *REFERENCE : draft-ietf-idr-ls-distribution-11 + 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 + +-+-+-+-+-+-+-+-+ + | Protocol-ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | + | (64 bits) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Local Node Descriptors (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure : The Node NLRI format + */ + + protected static final Logger log = LoggerFactory.getLogger(BGPNodeLSNlriVer4.class); + + public static final int NODE_NLRITYPE = 1; + public static final int IDENTIFIER_LENGTH = 16; + private long identifier; + private byte protocolId; + private BGPNodeLSIdentifier localNodeDescriptors; + private RouteDistinguisher routeDistinguisher; + private boolean isVpn; + + /** + * Enum to provide PROTOCOLTYPE. + */ + public enum PROTOCOLTYPE { + ISIS_LevelOne(1), ISIS_LevelTwo(2), OSPFv2(3), Direct(4), Static_Configuration(5), OSPFv3(6); + int value; + + /** + * Assign val with the value as the protocol type. + * + * @param val protocol type + */ + PROTOCOLTYPE(int val) { + value = val; + } + + /** + * Returns value of protocol type. + * + * @return protocol type + */ + public byte getType() { + return (byte) value; + } + } + + /** + * Reset fields. + */ + public BGPNodeLSNlriVer4() { + this.identifier = 0; + this.protocolId = 0; + this.localNodeDescriptors = null; + this.routeDistinguisher = null; + this.isVpn = false; + } + + /** + * Constructors to initialize its parameters. + * + * @param identifier of LinkState Nlri + * @param protocolId of LinkState Nlri + * @param localNodeDescriptors local node descriptors + * @param isVpn true if VPN info is present + * @param routeDistinguisher unique for each VPN + */ + BGPNodeLSNlriVer4(long identifier, byte protocolId, BGPNodeLSIdentifier localNodeDescriptors, boolean isVpn, + RouteDistinguisher routeDistinguisher) { + this.identifier = identifier; + this.protocolId = protocolId; + this.localNodeDescriptors = localNodeDescriptors; + this.routeDistinguisher = routeDistinguisher; + this.isVpn = isVpn; + } + + /** + * Reads from channelBuffer and parses Node LS Nlri. + * + * @param cb ChannelBuffer + * @param afi Address Family Identifier + * @param safi Subsequent Address Family Identifier + * @return object of this class + * @throws BGPParseException while parsing node descriptors + */ + public static BGPNodeLSNlriVer4 read(ChannelBuffer cb, short afi, byte safi) throws BGPParseException { + boolean isVpn = false; + RouteDistinguisher routeDistinguisher = null; + if ((afi == Constants.AFI_VALUE) && (safi == Constants.VPN_SAFI_VALUE)) { + routeDistinguisher = new RouteDistinguisher(); + routeDistinguisher = RouteDistinguisher.read(cb); + isVpn = true; + } else { + isVpn = false; + } + byte protocolId = cb.readByte(); + long identifier = cb.readLong(); + + // Parse Local Node Descriptors + BGPNodeLSIdentifier localNodeDescriptors = new BGPNodeLSIdentifier(); + localNodeDescriptors = BGPNodeLSIdentifier.parseLocalNodeDescriptors(cb, protocolId); + return new BGPNodeLSNlriVer4(identifier, protocolId, localNodeDescriptors, isVpn, routeDistinguisher); + } + + @Override + public NlriType getNlriType() { + return NlriType.NODE; + } + + @Override + public BGPNodeLSIdentifier getLocalNodeDescriptors() { + return this.localNodeDescriptors; + } + + /** + * Returns whether VPN is present or not. + * + * @return whether VPN is present or not + */ + public boolean isVpnPresent() { + return this.isVpn; + } + + @Override + public RouteDistinguisher getRouteDistinguisher() { + return this.routeDistinguisher; + } + + @Override + public long getIdentifier() { + return this.identifier; + } + + /** + * Set the node LS identifier. + * + * @param localNodeDescriptors node LS identifier to set + */ + public void setNodeLSIdentifier(BGPNodeLSIdentifier localNodeDescriptors) { + this.localNodeDescriptors = localNodeDescriptors; + } + + @Override + public PROTOCOLTYPE getProtocolId() throws BGPParseException { + switch (protocolId) { + case Constants.ISIS_LEVELONE: + return PROTOCOLTYPE.ISIS_LevelOne; + case Constants.ISIS_LEVELTWO: + return PROTOCOLTYPE.ISIS_LevelTwo; + case Constants.OSPFV2: + return PROTOCOLTYPE.OSPFv2; + case Constants.DIRECT: + return PROTOCOLTYPE.Direct; + case Constants.STATIC_CONFIGURATION: + return PROTOCOLTYPE.Static_Configuration; + case Constants.OSPFV3: + return PROTOCOLTYPE.OSPFv3; + default: + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("protocolId", protocolId) + .add("identifier", identifier) + .add("RouteDistinguisher ", routeDistinguisher) + .add("localNodeDescriptors", localNodeDescriptors) + .toString(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java new file mode 100644 index 00000000..0f18c757 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java @@ -0,0 +1,205 @@ +/* + * 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.protocol.link_state; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.protocol.BGPPrefixLSNlri; +import org.onosproject.bgpio.protocol.NlriType; +import org.onosproject.bgpio.protocol.link_state.BGPNodeLSNlriVer4.PROTOCOLTYPE; +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.types.RouteDistinguisher; +import org.onosproject.bgpio.util.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Prefix IPV4 LS NLRI. + */ +public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { + + /* + * REFERENCE : draft-ietf-idr-ls-distribution-11 + * 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 + +-+-+-+-+-+-+-+-+ + | Protocol-ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | + | (64 bits) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Local Node Descriptor (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Prefix Descriptors (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure : The IPv4/IPv6 Topology Prefix NLRI format + */ + + protected static final Logger log = LoggerFactory.getLogger(BGPPrefixIPv4LSNlriVer4.class); + + public static final int PREFIX_IPV4_NLRITYPE = 3; + public static final int IDENTIFIER_LENGTH = 16; + private long identifier; + private byte protocolId; + private RouteDistinguisher routeDistinguisher; + private boolean isVpn; + private BGPPrefixLSIdentifier bgpPrefixLSIdentifier; + + /** + * Resets parameters. + */ + public BGPPrefixIPv4LSNlriVer4() { + this.identifier = 0; + this.protocolId = 0; + this.bgpPrefixLSIdentifier = null; + this.routeDistinguisher = null; + this.isVpn = false; + } + + /** + * Constructor to initialize parameters for BGP PrefixLSNlri. + * + * @param identifier field in BGP PrefixLSNlri + * @param protocolId protocol Id + * @param bgpPrefixLSIdentifier prefix LS Identifier + * @param routeDistinguisher RouteDistinguisher + * @param isVpn vpn availability in message + */ + public BGPPrefixIPv4LSNlriVer4(long identifier, byte protocolId, BGPPrefixLSIdentifier bgpPrefixLSIdentifier, + RouteDistinguisher routeDistinguisher, boolean isVpn) { + this.identifier = identifier; + this.protocolId = protocolId; + this.bgpPrefixLSIdentifier = bgpPrefixLSIdentifier; + this.routeDistinguisher = routeDistinguisher; + this.isVpn = isVpn; + } + + /** + * Reads from channelBuffer and parses Prefix LS Nlri. + * + * @param cb ChannelBuffer + * @param afi Address family identifier + * @param safi Subsequent address family identifier + * @return object of BGPPrefixIPv4LSNlriVer4 + * @throws BGPParseException while parsing Prefix LS Nlri + */ + public static BGPPrefixIPv4LSNlriVer4 read(ChannelBuffer cb, short afi, byte safi) throws BGPParseException { + + boolean isVpn = false; + RouteDistinguisher routeDistinguisher = null; + if ((afi == Constants.AFI_VALUE) && (safi == Constants.VPN_SAFI_VALUE)) { + routeDistinguisher = new RouteDistinguisher(); + routeDistinguisher = RouteDistinguisher.read(cb); + isVpn = true; + } else { + isVpn = false; + } + byte protocolId = cb.readByte(); + long identifier = cb.readLong(); + + BGPPrefixLSIdentifier bgpPrefixLSIdentifier = new BGPPrefixLSIdentifier(); + bgpPrefixLSIdentifier = BGPPrefixLSIdentifier.parsePrefixIdendifier(cb, protocolId); + return new BGPPrefixIPv4LSNlriVer4(identifier, protocolId, bgpPrefixLSIdentifier, routeDistinguisher, isVpn); + } + + @Override + public NlriType getNlriType() { + return NlriType.PREFIX_IPV4; + } + + @Override + public NodeDescriptors getLocalNodeDescriptors() { + return this.bgpPrefixLSIdentifier.getLocalNodeDescriptors(); + } + + @Override + public long getIdentifier() { + return this.identifier; + } + + /** + * Set the prefix LS identifier. + * + * @param bgpPrefixLSIdentifier prefix identifier to set + */ + public void setPrefixLSIdentifier(BGPPrefixLSIdentifier bgpPrefixLSIdentifier) { + this.bgpPrefixLSIdentifier = bgpPrefixLSIdentifier; + } + + @Override + public PROTOCOLTYPE getProtocolId() throws BGPParseException { + switch (protocolId) { + case Constants.ISIS_LEVELONE: + return PROTOCOLTYPE.ISIS_LevelOne; + case Constants.ISIS_LEVELTWO: + return PROTOCOLTYPE.ISIS_LevelTwo; + case Constants.OSPFV2: + return PROTOCOLTYPE.OSPFv2; + case Constants.DIRECT: + return PROTOCOLTYPE.Direct; + case Constants.STATIC_CONFIGURATION: + return PROTOCOLTYPE.Static_Configuration; + case Constants.OSPFV3: + return PROTOCOLTYPE.OSPFv3; + default: + throw new BGPParseException("protocol id not valid"); + } + } + + /** + * Returns whether VPN is present or not. + * + * @return whether VPN is present or not + */ + public boolean isVpnPresent() { + return this.isVpn; + } + + /** + * Returns Prefix Identifier. + * + * @return Prefix Identifier + */ + public BGPPrefixLSIdentifier getPrefixIdentifier() { + return this.bgpPrefixLSIdentifier; + } + + @Override + public RouteDistinguisher getRouteDistinguisher() { + return this.routeDistinguisher; + } + + @Override + public LinkedList getPrefixdescriptor() { + return this.bgpPrefixLSIdentifier.getPrefixdescriptor(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("protocolId", protocolId) + .add("identifier", identifier) + .add("RouteDistinguisher ", routeDistinguisher) + .add("bgpPrefixLSIdentifier", bgpPrefixLSIdentifier) + .toString(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java index a6668b3a..10e6bb95 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java @@ -97,21 +97,6 @@ class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg { static class Builder implements BGPKeepaliveMsg.Builder { BGPHeader bgpMsgHeader; - @Override - public BGPVersion getVersion() { - return BGPVersion.BGP_4; - } - - @Override - public BGPType getType() { - return BGPType.KEEP_ALIVE; - } - - @Override - public BGPHeader getHeader() { - return this.bgpMsgHeader; - } - @Override public Builder setHeader(BGPHeader bgpMsgHeader) { this.bgpMsgHeader = bgpMsgHeader; diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java new file mode 100644 index 00000000..064deada --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java @@ -0,0 +1,266 @@ +/* + * 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.protocol.ver4; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.protocol.BGPMessageReader; +import org.onosproject.bgpio.protocol.BGPMessageWriter; +import org.onosproject.bgpio.protocol.BGPNotificationMsg; +import org.onosproject.bgpio.protocol.BGPType; +import org.onosproject.bgpio.protocol.BGPVersion; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.BGPHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * A NOTIFICATION message is sent when an error condition is detected. The BGP connection is closed immediately after it + * is sent. + */ +class BGPNotificationMsgVer4 implements BGPNotificationMsg { + + /* + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Error code | Error subcode | Data (variable) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + REFERENCE : RFC 4271 + */ + + protected static final Logger log = LoggerFactory.getLogger(BGPNotificationMsgVer4.class); + + static final byte PACKET_VERSION = 4; + //BGPHeader(19) + Error code(1) + Error subcode(1) + static final int TOTAL_MESSAGE_MIN_LENGTH = 21; + static final int PACKET_MINIMUM_LENGTH = 2; + static final BGPType MSG_TYPE = BGPType.NOTIFICATION; + static final byte DEFAULT_ERRORSUBCODE = 0; + static final byte[] MARKER = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01}; + static final byte MESSAGE_TYPE = 3; + static final BGPHeader DEFAULT_MESSAGE_HEADER = new BGPHeader(MARKER, BGPHeader.DEFAULT_HEADER_LENGTH, + MESSAGE_TYPE); + + private byte errorCode; + private byte errorSubCode; + private byte[] data; + private BGPHeader bgpHeader; + public static final BGPNotificationMsgVer4.Reader READER = new Reader(); + + /** + * Resets fields. + */ + public BGPNotificationMsgVer4() { + this.bgpHeader = null; + this.data = null; + this.errorCode = 0; + this.errorSubCode = 0; + } + + /** + * Constructor to initialize parameters. + * + * @param bgpHeader BGP Header in notification message + * @param errorCode error code + * @param errorSubCode error subcode + * @param data field + */ + public BGPNotificationMsgVer4(BGPHeader bgpHeader, byte errorCode, byte errorSubCode, byte[] data) { + this.bgpHeader = bgpHeader; + this.data = data; + this.errorCode = errorCode; + this.errorSubCode = errorSubCode; + } + + /** + * Reader reads BGP Notification Message from the channel buffer. + */ + static class Reader implements BGPMessageReader { + @Override + public BGPNotificationMsg readFrom(ChannelBuffer cb, BGPHeader bgpHeader) throws BGPParseException { + byte errorCode; + byte errorSubCode; + if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { + throw new BGPParseException("Not enough readable bytes"); + } + errorCode = cb.readByte(); + errorSubCode = cb.readByte(); + //Message Length = 21 + Data Length + int dataLength = bgpHeader.getLength() - TOTAL_MESSAGE_MIN_LENGTH; + byte[] data = new byte[dataLength]; + cb.readBytes(data, 0, dataLength); + return new BGPNotificationMsgVer4(bgpHeader, errorCode, errorSubCode, data); + } + } + + /** + * Builder class for BGP notification message. + */ + static class Builder implements BGPNotificationMsg.Builder { + private byte errorCode; + private byte errorSubCode; + private byte[] data; + private BGPHeader bgpHeader; + private boolean isErrorCodeSet = false; + private boolean isErrorSubCodeSet = false; + private boolean isBGPHeaderSet = false; + + @Override + public BGPNotificationMsg build() throws BGPParseException { + BGPHeader bgpHeader = this.isBGPHeaderSet ? this.bgpHeader : DEFAULT_MESSAGE_HEADER; + if (!this.isErrorCodeSet) { + throw new BGPParseException("Error code must be present"); + } + + byte errorSubCode = this.isErrorSubCodeSet ? this.errorSubCode : DEFAULT_ERRORSUBCODE; + return new BGPNotificationMsgVer4(bgpHeader, this.errorCode, errorSubCode, this.data); + } + + @Override + public Builder setErrorCode(byte errorCode) { + this.errorCode = errorCode; + this.isErrorCodeSet = true; + return this; + } + + @Override + public Builder setErrorSubCode(byte errorSubCode) { + this.errorSubCode = errorSubCode; + this.isErrorSubCodeSet = true; + return this; + } + + @Override + public Builder setData(byte[] data) { + this.data = data; + return this; + } + + @Override + public Builder setNotificationMsgHeader(BGPHeader header) { + this.bgpHeader = header; + this.isBGPHeaderSet = true; + return this; + } + + @Override + public Builder setHeader(BGPHeader bgpMsgHeader) { + this.bgpHeader = bgpMsgHeader; + return this; + } + } + + @Override + public BGPVersion getVersion() { + return BGPVersion.BGP_4; + } + + @Override + public BGPType getType() { + return BGPType.NOTIFICATION; + } + + @Override + public void writeTo(ChannelBuffer cb) throws BGPParseException { + WRITER.write(cb, this); + } + + static final Writer WRITER = new Writer(); + + /** + * Writer writes BGP notification message to channel buffer. + */ + static class Writer implements BGPMessageWriter { + @Override + public void write(ChannelBuffer cb, BGPNotificationMsgVer4 message) throws BGPParseException { + int msgStartIndex = cb.writerIndex(); + int headerLenIndex = message.bgpHeader.write(cb); + if (headerLenIndex <= 0) { + throw new BGPParseException(BGPErrorType.MESSAGE_HEADER_ERROR, (byte) 0, null); + } + cb.writeByte(message.errorCode); + cb.writeByte(message.errorSubCode); + cb.writeBytes(message.data); + + //Update message length field in notification message + int length = cb.writerIndex() - msgStartIndex; + cb.setShort(headerLenIndex, (short) length); + message.bgpHeader.setLength((short) length); + } + } + + @Override + public byte getErrorCode() { + return this.errorCode; + } + + /** + * Sets errorcode with specified errorcode. + * + * @param errorCode field + */ + public void setErrorCode(byte errorCode) { + this.errorCode = errorCode; + } + + @Override + public byte getErrorSubCode() { + return this.errorSubCode; + } + + /** + * Sets error subcode with specified errorSubCode. + * + * @param errorSubCode field + */ + public void setErrorSubCode(byte errorSubCode) { + this.errorSubCode = errorSubCode; + } + + @Override + public byte[] getData() { + return this.data; + } + + /** + * Sets error data with specified data. + * + * @param data field + */ + public void setData(byte[] data) { + this.data = data; + } + + @Override + public BGPHeader getHeader() { + return this.bgpHeader; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("bgpHeader", bgpHeader) + .add("data", data) + .add("errorCode", errorCode) + .add("errorSubCode", errorSubCode) + .toString(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java index 1348ecfd..b50342d6 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.onosproject.bgpio.protocol.ver4; import java.util.LinkedList; @@ -29,6 +28,8 @@ import org.onosproject.bgpio.protocol.BGPVersion; import org.onosproject.bgpio.types.BGPErrorType; import org.onosproject.bgpio.types.BGPHeader; import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv; +import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,8 +68,13 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { public static final int MSG_HEADER_LENGTH = 19; public static final int MARKER_LENGTH = 16; public static final int DEFAULT_HOLD_TIME = 120; + public static final short AS_TRANS = 23456; public static final int OPT_PARA_TYPE_CAPABILITY = 2; public static final BGPType MSG_TYPE = BGPType.OPEN; + public static final short AFI = 16388; + public static final byte SAFI = 71; + public static final byte RES = 0; + public static final int FOUR_OCTET_AS_NUM_CAPA_TYPE = 65; public static final byte[] MARKER = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; @@ -79,6 +85,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { private short asNumber; private short holdTime; private int bgpId; + private boolean isLargeAsCapabilitySet; private LinkedList capabilityTlv; public static final BGPOpenMsgVer4.Reader READER = new Reader(); @@ -98,18 +105,12 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { /** * Constructor to initialize all variables of BGP Open message. * - * @param bgpMsgHeader - * BGP Header in open message - * @param version - * BGP version in open message - * @param holdTime - * hold time in open message - * @param asNumber - * AS number in open message - * @param bgpId - * BGP identifier in open message - * @param capabilityTlv - * capabilities in open message + * @param bgpMsgHeader BGP Header in open message + * @param version BGP version in open message + * @param holdTime hold time in open message + * @param asNumber AS number in open message + * @param bgpId BGP identifier in open message + * @param capabilityTlv capabilities in open message */ public BGPOpenMsgVer4(BGPHeader bgpMsgHeader, byte version, short asNumber, short holdTime, int bgpId, LinkedList capabilityTlv) { @@ -236,7 +237,44 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { LinkedList capabilityTlv = new LinkedList<>(); - // TODO: Capability parsing + while (cb.readableBytes() > 0) { + BGPValueType tlv; + short type = cb.readByte(); + short length = cb.readByte(); + + switch (type) { + case FourOctetAsNumCapabilityTlv.TYPE: + log.debug("FourOctetAsNumCapabilityTlv"); + if (FourOctetAsNumCapabilityTlv.LENGTH != length) { + throw new BGPParseException("Invalid length received for FourOctetAsNumCapabilityTlv."); + } + if (length > cb.readableBytes()) { + throw new BGPParseException("Four octet as num tlv length" + + " is more than readableBytes."); + } + int as4Num = cb.readInt(); + tlv = new FourOctetAsNumCapabilityTlv(as4Num); + break; + case MultiProtocolExtnCapabilityTlv.TYPE: + log.debug("MultiProtocolExtnCapabilityTlv"); + if (MultiProtocolExtnCapabilityTlv.LENGTH != length) { + throw new BGPParseException("Invalid length received for MultiProtocolExtnCapabilityTlv."); + } + if (length > cb.readableBytes()) { + throw new BGPParseException("BGP LS tlv length is more than readableBytes."); + } + short afi = cb.readShort(); + byte res = cb.readByte(); + byte safi = cb.readByte(); + tlv = new MultiProtocolExtnCapabilityTlv(afi, res, safi); + break; + default: + log.debug("Warning: Unsupported TLV: " + type); + cb.skipBytes(length); + continue; + } + capabilityTlv.add(tlv); + } return capabilityTlv; } @@ -248,11 +286,13 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { private boolean isHeaderSet = false; private BGPHeader bgpMsgHeader; private boolean isHoldTimeSet = false; - private short holdTime; + private short holdTime; private boolean isAsNumSet = false; private short asNumber; private boolean isBgpIdSet = false; private int bgpId; + private boolean isLargeAsCapabilityTlvSet = false; + private boolean isLsCapabilityTlvSet = false; LinkedList capabilityTlv = new LinkedList<>(); @@ -269,33 +309,29 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { throw new BGPParseException("BGPID is not set (mandatory)"); } - // TODO: capabilities build + if (this.isLargeAsCapabilityTlvSet) { + BGPValueType tlv; + int iValue = this.getAsNumber(); + tlv = new FourOctetAsNumCapabilityTlv(iValue); + this.capabilityTlv.add(tlv); + } + + if (this.isLsCapabilityTlvSet) { + BGPValueType tlv; + tlv = new MultiProtocolExtnCapabilityTlv(AFI, RES, SAFI); + this.capabilityTlv.add(tlv); + } return new BGPOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId, this.capabilityTlv); } - @Override - public BGPHeader getHeader() { - return this.bgpMsgHeader; - } - @Override public Builder setHeader(BGPHeader bgpMsgHeader) { this.bgpMsgHeader = bgpMsgHeader; return this; } - @Override - public BGPVersion getVersion() { - return BGPVersion.BGP_4; - } - - @Override - public BGPType getType() { - return MSG_TYPE; - } - @Override public short getHoldTime() { return this.holdTime; @@ -342,6 +378,18 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { this.capabilityTlv = capabilityTlv; return this; } + + @Override + public Builder setLargeAsCapabilityTlv(boolean isLargeAsCapabilitySet) { + this.isLargeAsCapabilityTlvSet = isLargeAsCapabilitySet; + return this; + } + + @Override + public Builder setLsCapabilityTlv(boolean isLsCapabilitySet) { + this.isLsCapabilityTlvSet = isLsCapabilitySet; + return this; + } } @Override @@ -364,6 +412,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { public void write(ChannelBuffer cb, BGPOpenMsgVer4 message) throws BGPParseException { int optParaLen = 0; + int as4num = 0; int startIndex = cb.writerIndex(); @@ -377,8 +426,29 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { // write version in 1-octet cb.writeByte(message.version); - // TODO : Write AS number based on capabilities - cb.writeShort(message.asNumber); + // get as4num if LS Capability is set + if (message.isLargeAsCapabilitySet) { + LinkedList capabilityTlv = message + .getCapabilityTlv(); + ListIterator listIterator = capabilityTlv + .listIterator(); + + while (listIterator.hasNext()) { + BGPValueType tlv = listIterator.next(); + if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { + as4num = ((FourOctetAsNumCapabilityTlv) tlv).getInt(); + break; + } + } + } + + if ((message.isLargeAsCapabilitySet) && (as4num > 65535)) { + // write As number as AS_TRANS + cb.writeShort(AS_TRANS); + } else { + // write AS number in next 2-octet + cb.writeShort(message.asNumber); + } // write HoldTime in next 2-octet cb.writeShort(message.holdTime); diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java new file mode 100755 index 00000000..61570285 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java @@ -0,0 +1,114 @@ +/* + * 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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides FourOctetAsNumCapabilityTlv Capability Tlv. + */ +public class FourOctetAsNumCapabilityTlv implements BGPValueType { + + /** + * support to indicate its support for four-octet AS numbers -CAPABILITY TLV format. + */ + protected static final Logger log = LoggerFactory + .getLogger(FourOctetAsNumCapabilityTlv.class); + + public static final byte TYPE = 65; + public static final byte LENGTH = 4; + + private final int rawValue; + + /** + * constructor to initialize rawValue. + * @param rawValue FourOctetAsNumCapabilityTlv + */ + public FourOctetAsNumCapabilityTlv(int rawValue) { + this.rawValue = rawValue; + } + + /** + * constructor to initialize raw. + * @param raw AS number + * @return object of FourOctetAsNumCapabilityTlv + */ + public static FourOctetAsNumCapabilityTlv of(final int raw) { + return new FourOctetAsNumCapabilityTlv(raw); + } + + /** + * Returns value of TLV. + * @return int value of rawValue + */ + public int getInt() { + return rawValue; + } + + @Override + public short getType() { + return TYPE; + } + + @Override + public int hashCode() { + return Objects.hash(rawValue); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof FourOctetAsNumCapabilityTlv) { + FourOctetAsNumCapabilityTlv other = (FourOctetAsNumCapabilityTlv) obj; + return Objects.equals(rawValue, other.rawValue); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + int iLenStartIndex = cb.writerIndex(); + cb.writeByte(TYPE); + cb.writeByte(LENGTH); + cb.writeInt(rawValue); + return cb.writerIndex() - iLenStartIndex; + } + + /** + * Reads the channel buffer and returns object of FourOctetAsNumCapabilityTlv. + * @param cb type of channel buffer + * @return object of FourOctetAsNumCapabilityTlv + */ + public static FourOctetAsNumCapabilityTlv read(ChannelBuffer cb) { + return FourOctetAsNumCapabilityTlv.of(cb.readInt()); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("Type", TYPE) + .add("Length", LENGTH) + .add("Value", rawValue).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java new file mode 100755 index 00000000..9beff68c --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java @@ -0,0 +1,160 @@ +/* + * 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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides MultiProtocolExtnCapabilityTlv. + */ +public class MultiProtocolExtnCapabilityTlv implements BGPValueType { + + /* + 0 7 15 23 31 + +-------+-------+-------+-------+ + | AFI | Res | SAFI | + +-------+-------+-------+-------+ + + Multiprotocol Extensions CAPABILITY TLV format + REFERENCE : RFC 4760 + */ + protected static final Logger log = LoggerFactory + .getLogger(MultiProtocolExtnCapabilityTlv.class); + + public static final byte TYPE = 1; + public static final byte LENGTH = 4; + + private final short afi; + private final byte res; + private final byte safi; + + /** + * Constructor to initialize variables. + * @param afi Address Family Identifiers + * @param res reserved field + * @param safi Subsequent Address Family Identifier + */ + public MultiProtocolExtnCapabilityTlv(short afi, byte res, byte safi) { + this.afi = afi; + this.res = res; + this.safi = safi; + } + + /** + * Returns object of MultiProtocolExtnCapabilityTlv. + * @param afi Address Family Identifiers + * @param res reserved field + * @param safi Subsequent Address Family Identifier + * @return object of MultiProtocolExtnCapabilityTlv + */ + public static MultiProtocolExtnCapabilityTlv of(short afi, byte res, + byte safi) { + return new MultiProtocolExtnCapabilityTlv(afi, res, safi); + } + + /** + * Returns afi Address Family Identifiers value. + * @return afi Address Family Identifiers value + */ + public short getAFI() { + return afi; + } + + /** + * Returns res reserved field value. + * @return res reserved field value + */ + public byte getRes() { + return res; + } + + /** + * Returns safi Subsequent Address Family Identifier value. + * @return safi Subsequent Address Family Identifier value + */ + public byte getSAFI() { + return safi; + } + + @Override + public short getType() { + return TYPE; + } + + @Override + public int hashCode() { + return Objects.hash(afi, res, safi); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof MultiProtocolExtnCapabilityTlv) { + MultiProtocolExtnCapabilityTlv other = (MultiProtocolExtnCapabilityTlv) obj; + return Objects.equals(this.afi, other.afi) + && Objects.equals(this.res, other.res) + && Objects.equals(this.safi, other.safi); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + int iLenStartIndex = cb.writerIndex(); + cb.writeByte(TYPE); + cb.writeByte(LENGTH); + + // write afi + cb.writeShort(afi); + + // write res + cb.writeByte(res); + + // write safi + cb.writeByte(safi); + + return cb.writerIndex() - iLenStartIndex; + } + + /** + * Reads from channel buffer and returns object of MultiprotocolCapabilityTlv. + * @param cb of type channel buffer + * @return object of MultiProtocolExtnCapabilityTlv + */ + public static BGPValueType read(ChannelBuffer cb) { + short afi = cb.readShort(); + byte res = cb.readByte(); + byte safi = cb.readByte(); + return new MultiProtocolExtnCapabilityTlv(afi, res, safi); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("Type", TYPE) + .add("Length", LENGTH) + .add("AFI", afi) + .add("Reserved", res) + .add("SAFI", safi).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java new file mode 100644 index 00000000..d0267092 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java @@ -0,0 +1,62 @@ +/* + * 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 org.jboss.netty.buffer.ChannelBuffer; + +/** + * Implementation of RouteDistinguisher. + */ +public class RouteDistinguisher { + + private long routeDistinguisher; + + /** + * Resets fields. + */ + public RouteDistinguisher() { + this.routeDistinguisher = 0; + } + + /** + * Constructor to initialize parameters. + * + * @param routeDistinguisher route distinguisher + */ + public RouteDistinguisher(long routeDistinguisher) { + this.routeDistinguisher = routeDistinguisher; + } + + /** + * Reads route distinguisher from channelBuffer. + * + * @param cb channelBuffer + * @return object of RouteDistinguisher + */ + public static RouteDistinguisher read(ChannelBuffer cb) { + return new RouteDistinguisher(cb.readLong()); + } + + /** + * Returns route distinguisher. + * + * @return route distinguisher + */ + public long getRouteDistinguisher() { + return this.routeDistinguisher; + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java new file mode 100755 index 00000000..00dffb58 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java @@ -0,0 +1,124 @@ +/* + * 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.attr; + +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.types.BGPErrorType; +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP attribute node router ID. + */ +public class BgpAttrRouterIdV4 implements BGPValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpAttrRouterIdV4.class); + + public short sType; + + /* IPv4 Router-ID of Node */ + private Ip4Address ip4RouterId; + + /** + * Constructor to initialize the value. + * + * @param ip4RouterId IPV4 address of router + * @param sType TLV type + */ + BgpAttrRouterIdV4(Ip4Address ip4RouterId, short sType) { + this.ip4RouterId = ip4RouterId; + this.sType = sType; + } + + /** + * Reads the IPv4 Router-ID. + * + * @param cb ChannelBuffer + * @return object of BgpAttrRouterIdV4 + * @throws BGPParseException while parsing BgpAttrNodeRouterId + */ + public static BgpAttrRouterIdV4 read(ChannelBuffer cb, short sType) + throws BGPParseException { + byte[] ipBytes; + Ip4Address ip4RouterId; + + short lsAttrLength = cb.readShort(); + + if (4 != lsAttrLength) { + Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, + BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + ipBytes = new byte[lsAttrLength]; + cb.readBytes(ipBytes); + ip4RouterId = Ip4Address.valueOf(ipBytes); + return new BgpAttrRouterIdV4(ip4RouterId, sType); + } + + /** + * Returns the IPV4 router ID. + * + * @return Router ID + */ + Ip4Address getAttrRouterId() { + return ip4RouterId; + } + + @Override + public short getType() { + return sType; + } + + @Override + public int hashCode() { + return Objects.hash(ip4RouterId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpAttrRouterIdV4) { + BgpAttrRouterIdV4 other = (BgpAttrRouterIdV4) obj; + return Objects.equals(ip4RouterId, other.ip4RouterId); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("ip4RouterId", ip4RouterId).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java new file mode 100755 index 00000000..561c3d4c --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java @@ -0,0 +1,124 @@ +/* + * 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.attr; + +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onlab.packet.Ip6Address; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP attribute IPv6 router ID. + */ +public class BgpAttrRouterIdV6 implements BGPValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpAttrRouterIdV6.class); + + public short sType; + + /* IPv4 Router-ID of Node */ + private Ip6Address ip6RouterId; + + /** + * Constructor to initialize the value. + * + * @param ip6RouterId IPV6 address of the router ID + * @param sType TLV type + */ + BgpAttrRouterIdV6(Ip6Address ip6RouterId, short sType) { + this.ip6RouterId = ip6RouterId; + this.sType = sType; + } + + /** + * Reads the IPv6 Router-ID. + * + * @param cb ChannelBuffer + * @return object of BgpAttrRouterIdV6 + * @throws BGPParseException while parsing BgpAttrRouterIdV6 + */ + public static BgpAttrRouterIdV6 read(ChannelBuffer cb, short sType) + throws BGPParseException { + byte[] ipBytes; + Ip6Address ip6RouterId; + + short lsAttrLength = cb.readShort(); + + if (16 != lsAttrLength) { + Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, + BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + ipBytes = new byte[lsAttrLength]; + cb.readBytes(ipBytes); + ip6RouterId = Ip6Address.valueOf(ipBytes); + return new BgpAttrRouterIdV6(ip6RouterId, sType); + } + + /** + * Returns IPV6 router ID. + * + * @return Router ID + */ + Ip6Address getAttrRouterId() { + return ip6RouterId; + } + + @Override + public short getType() { + return sType; + } + + @Override + public int hashCode() { + return Objects.hash(ip6RouterId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpAttrRouterIdV6) { + BgpAttrRouterIdV6 other = (BgpAttrRouterIdV6) obj; + return Objects.equals(ip6RouterId, other.ip6RouterId); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("ip6RouterId", ip6RouterId).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java new file mode 100755 index 00000000..50591ecf --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.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.attr; + +import java.util.Arrays; +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP link name attribute. + */ +public class BgpLinkAttrName implements BGPValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpLinkAttrName.class); + + public static final int ATTRLINK_NAME = 1098; + + /* Link Name */ + private byte[] linkName; + + /** + * Constructor to initialize the values. + * + * @param linkName link name + */ + BgpLinkAttrName(byte[] linkName) { + this.linkName = Arrays.copyOf(linkName, linkName.length); + } + + /** + * Reads the BGP link attributes Name. + * + * @param cb Channel buffer + * @return object of type BgpLinkAttrName + * @throws BGPParseException while parsing BgpLinkAttrName + */ + public static BgpLinkAttrName read(ChannelBuffer cb) + throws BGPParseException { + byte[] linkName; + short lsAttrLength = cb.readShort(); + + if (cb.readableBytes() < lsAttrLength) { + Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, + BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + linkName = new byte[lsAttrLength]; + cb.readBytes(linkName); + return new BgpLinkAttrName(linkName); + } + + /** + * Returns the link name. + * + * @return link name + */ + byte[] getAttrLinkName() { + return linkName; + } + + @Override + public short getType() { + return ATTRLINK_NAME; + } + + @Override + public int hashCode() { + return Objects.hash(linkName); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpLinkAttrName) { + BgpLinkAttrName other = (BgpLinkAttrName) obj; + return Objects.equals(linkName, other.linkName); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("linkName", linkName).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIGPFlags.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIGPFlags.java new file mode 100755 index 00000000..035d706c --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIGPFlags.java @@ -0,0 +1,180 @@ +/* + * 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.attr; + +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP prefix IGP Flag attribute. + */ +public class BgpPrefixAttrIGPFlags implements BGPValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpPrefixAttrIGPFlags.class); + + public static final int ATTR_PREFIX_FLAGBIT = 1152; + public static final int ATTR_PREFIX_FLAG_LEN = 1; + + public static final int FIRST_BIT = 0x80; + public static final int SECOND_BIT = 0x40; + public static final int THIRD_BIT = 0x20; + public static final int FOURTH_BIT = 0x01; + + /* Prefix IGP flag bit TLV */ + private boolean bisisUpDownBit = false; + private boolean bOspfNoUnicastBit = false; + private boolean bOspfLclAddrBit = false; + private boolean bOspfNSSABit = false; + + /** + * Constructor to initialize the value. + * + * @param bisisUpDownBit IS-IS Up/Down Bit + * @param bOspfNoUnicastBit OSPF no unicast Bit + * @param bOspfLclAddrBit OSPF local address Bit + * @param bOspfNSSABit OSPF propagate NSSA Bit + */ + BgpPrefixAttrIGPFlags(boolean bisisUpDownBit, boolean bOspfNoUnicastBit, + boolean bOspfLclAddrBit, boolean bOspfNSSABit) { + this.bisisUpDownBit = bisisUpDownBit; + this.bOspfNoUnicastBit = bOspfNoUnicastBit; + this.bOspfLclAddrBit = bOspfLclAddrBit; + this.bOspfNSSABit = bOspfNSSABit; + } + + /** + * Reads the IGP Flags. + * + * @param cb ChannelBuffer + * @return object of BgpPrefixAttrIGPFlags + * @throws BGPParseException while parsing BgpPrefixAttrIGPFlags + */ + public static BgpPrefixAttrIGPFlags read(ChannelBuffer cb) + throws BGPParseException { + boolean bisisUpDownBit = false; + boolean bOspfNoUnicastBit = false; + boolean bOspfLclAddrBit = false; + boolean bOspfNSSABit = false; + + short lsAttrLength = cb.readShort(); + + if ((lsAttrLength != ATTR_PREFIX_FLAG_LEN) + || (cb.readableBytes() < lsAttrLength)) { + Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, + BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + byte nodeFlagBits = cb.readByte(); + + bisisUpDownBit = ((nodeFlagBits & (byte) FIRST_BIT) == FIRST_BIT); + bOspfNoUnicastBit = ((nodeFlagBits & (byte) SECOND_BIT) == SECOND_BIT); + bOspfLclAddrBit = ((nodeFlagBits & (byte) THIRD_BIT) == THIRD_BIT); + bOspfNSSABit = ((nodeFlagBits & (byte) FOURTH_BIT) == FOURTH_BIT); + + return new BgpPrefixAttrIGPFlags(bisisUpDownBit, bOspfNoUnicastBit, + bOspfLclAddrBit, bOspfNSSABit); + } + + /** + * Returns the IS-IS Up/Down Bit set or not. + * + * @return IS-IS Up/Down Bit set or not + */ + boolean getisisUpDownBit() { + return bisisUpDownBit; + } + + /** + * Returns the OSPF no unicast Bit set or not. + * + * @return OSPF no unicast Bit set or not + */ + boolean getOspfNoUnicastBit() { + return bOspfNoUnicastBit; + } + + /** + * Returns the OSPF local address Bit set or not. + * + * @return OSPF local address Bit set or not + */ + boolean getOspfLclAddrBit() { + return bOspfLclAddrBit; + } + + /** + * Returns the OSPF propagate NSSA Bit set or not. + * + * @return OSPF propagate NSSA Bit set or not + */ + boolean getOspfNSSABit() { + return bOspfNSSABit; + } + + @Override + public short getType() { + return ATTR_PREFIX_FLAGBIT; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public int hashCode() { + return Objects.hash(bisisUpDownBit, bOspfNoUnicastBit, bOspfLclAddrBit, + bOspfNSSABit); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpPrefixAttrIGPFlags) { + BgpPrefixAttrIGPFlags other = (BgpPrefixAttrIGPFlags) obj; + return Objects.equals(bisisUpDownBit, other.bisisUpDownBit) + && Objects.equals(bOspfNoUnicastBit, + other.bOspfNoUnicastBit) + && Objects.equals(bOspfLclAddrBit, other.bOspfLclAddrBit) + && Objects.equals(bOspfNSSABit, other.bOspfNSSABit); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("bisisUpDownBit", bisisUpDownBit) + .add("bOspfNoUnicastBit", bOspfNoUnicastBit) + .add("bOspfLclAddrBit", bOspfLclAddrBit) + .add("bOspfNSSABit", bOspfNSSABit).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java new file mode 100755 index 00000000..0cf02386 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java @@ -0,0 +1,125 @@ +/* + * 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.attr; + +import java.util.Arrays; +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP prefix route tag attribute. + */ +public class BgpPrefixAttrRouteTag implements BGPValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpPrefixAttrRouteTag.class); + + public static final int ATTR_PREFIX_ROUTETAG = 1153; + + /* Prefix Route Tag */ + private int[] pfxRouteTag; + + /** + * Constructor to initialize the values. + * + * @param pfxRouteTag prefix route tag + */ + BgpPrefixAttrRouteTag(int[] pfxRouteTag) { + this.pfxRouteTag = Arrays.copyOf(pfxRouteTag, pfxRouteTag.length); + } + + /** + * Reads the Route Tag. + * + * @param cb ChannelBuffer + * @return object of BgpPrefixAttrRouteTag + * @throws BGPParseException while parsing BgpPrefixAttrRouteTag + */ + public static BgpPrefixAttrRouteTag read(ChannelBuffer cb) + throws BGPParseException { + int[] pfxRouteTag; + + short lsAttrLength = cb.readShort(); + int len = lsAttrLength / Integer.SIZE; + + if (cb.readableBytes() < lsAttrLength) { + Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, + BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + pfxRouteTag = new int[lsAttrLength]; + + for (int i = 0; i < len; i++) { + pfxRouteTag[i] = cb.readInt(); + } + + return new BgpPrefixAttrRouteTag(pfxRouteTag); + } + + /** + * Returns the prefix route tag. + * + * @return route tag + */ + int[] getPfxRouteTag() { + return pfxRouteTag; + } + + @Override + public short getType() { + return ATTR_PREFIX_ROUTETAG; + } + + @Override + public int hashCode() { + return Objects.hash(pfxRouteTag); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpPrefixAttrRouteTag) { + BgpPrefixAttrRouteTag other = (BgpPrefixAttrRouteTag) obj; + return Objects.equals(pfxRouteTag, other.pfxRouteTag); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("pfxRouteTag", pfxRouteTag).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java new file mode 100644 index 00000000..9649bf16 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java @@ -0,0 +1,37 @@ +/* + * 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.util; + +/** + * Provides Constants usage for BGP. + */ +public final class Constants { + private Constants() { + } + + public static final short TYPE_AND_LEN = 4; + public static final short TYPE_AND_LEN_AS_SHORT = 4; + public static final short TYPE_AND_LEN_AS_BYTE = 3; + public static final int ISIS_LEVELONE = 1; + public static final int ISIS_LEVELTWO = 2; + public static final int OSPFV2 = 3; + public static final int DIRECT = 4; + public static final int STATIC_CONFIGURATION = 5; + public static final int OSPFV3 = 6; + public static final short AFI_VALUE = 16388; + public static final byte VPN_SAFI_VALUE = (byte) 0x80; + public static final byte SAFI_VALUE = 71; +} \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java index 942d3658..c17736ed 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java @@ -16,19 +16,616 @@ package org.onosproject.bgp.controller.impl; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.channels.ClosedChannelException; +import java.util.Date; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; +import org.jboss.netty.handler.timeout.ReadTimeoutException; +import org.jboss.netty.handler.timeout.ReadTimeoutHandler; +import org.onlab.packet.IpAddress; +import org.onosproject.bgp.controller.BGPCfg; +import org.onosproject.bgp.controller.BGPId; +import org.onosproject.bgp.controller.BGPPeer; +import org.onosproject.bgp.controller.BGPPeerCfg; +import org.onosproject.bgp.controller.impl.BGPControllerImpl.BGPPeerManager; +import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.protocol.BGPMessage; +//import org.onosproject.bgpio.protocol.BGPOpenMsg; +import org.onosproject.bgpio.protocol.BGPType; +import org.onosproject.bgpio.protocol.BGPVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Channel handler deals with the bgp peer connection and dispatches messages from peer to the appropriate locations. */ class BGPChannelHandler extends IdleStateAwareChannelHandler { - // TODO: implement FSM and session handling mechanism + private static final Logger log = LoggerFactory.getLogger(BGPChannelHandler.class); + + static final int BGP_MAX_KEEPALIVE_INTERVAL = 3; + private BGPPeer bgpPeer; + private BGPId thisbgpId; + Channel channel; + private BGPKeepAliveTimer keepAliveTimer = null; + private short peerHoldTime = 0; + private short negotiatedHoldTime = 0; + private short peerAsNum; + private int peerIdentifier; + private BGPPacketStatsImpl bgpPacketStats; + static final int MAX_WRONG_COUNT_PACKET = 5; + + // State needs to be volatile because the HandshakeTimeoutHandler + // needs to check if the handshake is complete + private volatile ChannelState state; + + // When a bgp peer with a ip addresss is found (i.e we already have a + // connected peer with the same ip), the new peer is immediately + // disconnected. At that point netty callsback channelDisconnected() which + // proceeds to cleaup peer state - we need to ensure that it does not cleanup + // peer state for the older (still connected) peer + private volatile Boolean duplicateBGPIdFound; + // Indicates the bgp version used by this bgp peer + protected BGPVersion bgpVersion; + private BGPControllerImpl bgpControllerImpl; + private BGPPeerManager peerManager; + private InetSocketAddress inetAddress; + private IpAddress ipAddress; + private SocketAddress address; + private String peerAddr; + private BGPCfg bgpconfig; + /** * Create a new unconnected BGPChannelHandler. * * @param bgpCtrlImpl bgp controller implementation object */ BGPChannelHandler(BGPControllerImpl bgpCtrlImpl) { + this.bgpControllerImpl = bgpCtrlImpl; + this.peerManager = bgpCtrlImpl.getPeerManager(); + this.state = ChannelState.IDLE; + this.duplicateBGPIdFound = Boolean.FALSE; + this.bgpPacketStats = new BGPPacketStatsImpl(); + this.bgpconfig = bgpCtrlImpl.getConfig(); + } + + // To disconnect peer session. + public void disconnectPeer() { + bgpPeer.disconnectPeer(); + } + + // ************************* + // Channel State Machine + // ************************* + + /** + * The state machine for handling the peer/channel state. All state transitions should happen from within the state + * machine (and not from other parts of the code) + */ + enum ChannelState { + /** + * Initial state before channel is connected. + */ + IDLE(false) { + + }, + + OPENSENT(false) { + @Override + void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + log.debug("message received in OPENSENT state"); + // check for OPEN message + if (m.getType() != BGPType.OPEN) { + // When the message type is not keep alive message increment the wrong packet statistics + h.processUnknownMsg(); + log.debug("Message is not OPEN message"); + } else { + log.debug("Sending keep alive message in OPENSENT state"); + h.bgpPacketStats.addInPacket(); + + // TODO: initialize openmessage BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; + // TODO: initialize identifier from open messgae h.peerIdentifier = pOpenmsg.getBgpId(); + + // validate capabilities and open msg + if (h.openMsgValidation(h)) { + log.debug("Sending handshake OPEN message"); + + /* + * RFC 4271, section 4.2: Upon receipt of an OPEN message, a BGP speaker MUST calculate the + * value of the Hold Timer by using the smaller of its configured Hold Time and the Hold Time + * received in the OPEN message + */ + // TODO: initialize holdtime from open message h.peerHoldTime = pOpenmsg.getHoldTime(); + if (h.peerHoldTime < h.bgpconfig.getHoldTime()) { + h.channel.getPipeline().replace("holdTime", + "holdTime", + new ReadTimeoutHandler(BGPPipelineFactory.TIMER, + h.peerHoldTime)); + } + + log.info("Hold Time : " + h.peerHoldTime); + + // TODO: get AS number for open message update AS number + } + + // Send keepalive message to peer. + h.sendKeepAliveMessage(); + h.bgpPacketStats.addOutPacket(); + h.setState(OPENCONFIRM); + h.bgpconfig.setPeerConnState(h.peerAddr, BGPPeerCfg.State.OPENCONFIRM); + } + } + }, + + OPENWAIT(false) { + @Override + void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + log.debug("Message received in OPEN WAIT State"); + + // check for open message + if (m.getType() != BGPType.OPEN) { + // When the message type is not open message increment the wrong packet statistics + h.processUnknownMsg(); + log.debug("Message is not OPEN message"); + } else { + h.bgpPacketStats.addInPacket(); + + // TODO: initialize open message BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; + + // Validate open message + if (h.openMsgValidation(h)) { + log.debug("Sending handshake OPEN message"); + + /* + * RFC 4271, section 4.2: Upon receipt of an OPEN message, a BGP speaker MUST calculate the + * value of the Hold Timer by using the smaller of its configured Hold Time and the Hold Time + * received in the OPEN message + */ + // TODO: get hold time from open message h.peerHoldTime = pOpenmsg.getHoldTime(); + if (h.peerHoldTime < h.bgpconfig.getHoldTime()) { + h.channel.getPipeline().replace("holdTime", + "holdTime", + new ReadTimeoutHandler(BGPPipelineFactory.TIMER, + h.peerHoldTime)); + } + + log.debug("Hold Time : " + h.peerHoldTime); + + //TODO: update AS number form open messsage update AS number + + h.sendHandshakeOpenMessage(); + h.bgpPacketStats.addOutPacket(); + h.setState(OPENCONFIRM); + } + } + } + }, + + OPENCONFIRM(false) { + @Override + void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + log.debug("Message received in OPENCONFIRM state"); + // check for keep alive message + if (m.getType() != BGPType.KEEP_ALIVE) { + // When the message type is not keep alive message handle the wrong packet + h.processUnknownMsg(); + log.debug("Message is not KEEPALIVE message"); + } else { + + // Set the peer connected status + h.bgpPacketStats.addInPacket(); + log.debug("Sending keep alive message in OPENCONFIRM state"); + + final InetSocketAddress inetAddress = (InetSocketAddress) h.address; + h.thisbgpId = BGPId.bgpId(IpAddress.valueOf(inetAddress.getAddress())); + + h.bgpPeer = h.peerManager.getBGPPeerInstance(h.thisbgpId, h.bgpVersion, h.bgpPacketStats); + // set the status fo bgp as connected + h.bgpPeer.setConnected(true); + h.bgpPeer.setChannel(h.channel); + + // set specific parameters to bgp peer + h.bgpPeer.setBgpPeerVersion(h.bgpVersion); + h.bgpPeer.setBgpPeerASNum(h.peerAsNum); + h.bgpPeer.setBgpPeerHoldTime(h.peerHoldTime); + h.bgpPeer.setBgpPeerIdentifier(h.peerIdentifier); + + h.negotiatedHoldTime = (h.peerHoldTime < h.bgpconfig.getHoldTime()) ? h.peerHoldTime : h.bgpconfig + .getHoldTime(); + h.bgpPeer.setNegotiatedHoldTime(h.negotiatedHoldTime); + /* + * RFC 4271, When an OPEN message is received, sends a KEEPALIVE message, If the negotiated hold + * time value is zero, then the HoldTimer and KeepaliveTimer are not started. A reasonable maximum + * time between KEEPALIVE messages would be one third of the Hold Time interval. + */ + h.sendKeepAliveMessage(); + + if (h.negotiatedHoldTime != 0) { + h.keepAliveTimer + = new BGPKeepAliveTimer(h, (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL)); + } + + h.bgpPacketStats.addOutPacket(); + + // set the state handshake completion. + h.setHandshakeComplete(true); + + if (!h.peerManager.addConnectedPeer(h.thisbgpId, h.bgpPeer)) { + /* + * RFC 4271, Section 6.8, Based on the value of the BGP identifier, a convention is established + * for detecting which BGP connection is to be preserved when a collision occurs. The convention + * is to compare the BGP Identifiers of the peers involved in the collision and to retain only + * the connection initiated by the BGP speaker with the higher-valued BGP Identifier.. + */ + // TODO: Connection collision handling. + disconnectDuplicate(h); + } else { + h.setState(ESTABLISHED); + h.bgpconfig.setPeerConnState(h.peerAddr, BGPPeerCfg.State.ESTABLISHED); + } + } + } + }, + + ESTABLISHED(true) { + @Override + void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + log.debug("Message received in established state " + m.getType()); + // dispatch the message + h.dispatchMessage(m); + } + }; + + private boolean handshakeComplete; + + ChannelState(boolean handshakeComplete) { + this.handshakeComplete = handshakeComplete; + } + + /** + * Is this a state in which the handshake has completed? + * + * @return true if the handshake is complete + */ + public boolean isHandshakeComplete() { + return this.handshakeComplete; + } + + /** + * Disconnect duplicate peer connection. + * + * @param h channel handler + */ + protected void disconnectDuplicate(BGPChannelHandler h) { + log.error("Duplicated BGP IP or incompleted cleanup - " + "" + "disconnecting channel {}", + h.getPeerInfoString()); + h.duplicateBGPIdFound = Boolean.TRUE; + h.channel.disconnect(); + } + + // set handshake completion status + public void setHandshakeComplete(boolean handshakeComplete) { + this.handshakeComplete = handshakeComplete; + } + + void processBGPMessage(BGPChannelHandler bgpChannelHandler, BGPMessage pm) + throws IOException, BGPParseException { + // TODO Auto-generated method stub + log.debug("BGP message stub"); + } + + } + + // ************************* + // Channel handler methods + // ************************* + + @Override + public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + + channel = e.getChannel(); + log.info("BGP connected from {}", channel.getRemoteAddress()); + + address = channel.getRemoteAddress(); + if (!(address instanceof InetSocketAddress)) { + throw new IOException("Invalid peer connection."); + } + + // Connection should establish only if local ip and Autonomous system number is configured. + if (bgpconfig.getState() != BGPCfg.State.IP_AS_CONFIGURED) { + channel.close(); + log.info("BGP local AS and router ID not configured"); + return; + } + + inetAddress = (InetSocketAddress) address; + ipAddress = IpAddress.valueOf(inetAddress.getAddress()); + peerAddr = ipAddress.toString(); + + // if peer is not configured disconnect session + if (!bgpconfig.isPeerConfigured(peerAddr)) { + log.debug("Peer is not configured {}", peerAddr); + channel.close(); + return; + } + + // if connection is already established close channel + if (peerManager.isPeerConnected(peerAddr)) { + log.debug("Duplicate connection received, peer {}", peerAddr); + channel.close(); + return; + } + + if (null != channel.getPipeline().get("PassiveHandler")) { + log.info("BGP handle connection request from peer"); + // Wait for open message from bgp peer + setState(ChannelState.OPENWAIT); + } else if (null != channel.getPipeline().get("ActiveHandler")) { + log.info("BGP handle connection response from peer"); + + sendHandshakeOpenMessage(); + bgpPacketStats.addOutPacket(); + setState(ChannelState.OPENSENT); + bgpconfig.setPeerConnState(peerAddr, BGPPeerCfg.State.OPENSENT); + } + } + + @Override + public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + + channel = e.getChannel(); + log.info("BGP disconnected callback for bgp:{}. Cleaning up ...", getPeerInfoString()); + + address = channel.getRemoteAddress(); + if (!(address instanceof InetSocketAddress)) { + throw new IOException("Invalid peer connection."); + } + + inetAddress = (InetSocketAddress) address; + ipAddress = IpAddress.valueOf(inetAddress.getAddress()); + peerAddr = ipAddress.toString(); + + if (thisbgpId != null) { + if (!duplicateBGPIdFound) { + // if the disconnected peer (on this ChannelHandler) + // was not one with a duplicate, it is safe to remove all + // state for it at the controller. Notice that if the disconnected + // peer was a duplicate-ip, calling the method below would clear + // all state for the original peer (with the same ip), + // which we obviously don't want. + log.debug("{}:removal called", getPeerInfoString()); + if (bgpPeer != null) { + peerManager.removeConnectedPeer(thisbgpId); + } + } else { + // A duplicate was disconnected on this ChannelHandler, + // this is the same peer reconnecting, but the original state was + // not cleaned up - XXX check liveness of original ChannelHandler + log.debug("{}:duplicate found", getPeerInfoString()); + duplicateBGPIdFound = Boolean.FALSE; + } + + if (null != keepAliveTimer) { + keepAliveTimer.getKeepAliveTimer().cancel(); + } + } else { + log.warn("No bgp ip in channelHandler registered for " + "disconnected peer {}", getPeerInfoString()); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + + log.info("[exceptionCaught]: " + e.toString()); + + if (e.getCause() instanceof ReadTimeoutException) { + if ((ChannelState.OPENWAIT == state) || (ChannelState.OPENSENT == state)) { + + // When ReadTimeout timer is expired in OPENWAIT/OPENSENT state, it is considered + // TODO: Send notification + channel.close(); + state = ChannelState.IDLE; + return; + } else if (ChannelState.OPENCONFIRM == state) { + + // When ReadTimeout timer is expired in OPENCONFIRM state. + // TODO: Send Notification + channel.close(); + state = ChannelState.IDLE; + return; + } + } else if (e.getCause() instanceof ClosedChannelException) { + log.debug("Channel for bgp {} already closed", getPeerInfoString()); + } else if (e.getCause() instanceof IOException) { + log.error("Disconnecting peer {} due to IO Error: {}", getPeerInfoString(), e.getCause().getMessage()); + if (log.isDebugEnabled()) { + // still print stack trace if debug is enabled + log.debug("StackTrace for previous Exception: ", e.getCause()); + } + channel.close(); + } else if (e.getCause() instanceof BGPParseException) { + // TODO: SEND NOTIFICATION + log.debug("BGP Parse Exception: ", e.getCause()); + } else if (e.getCause() instanceof RejectedExecutionException) { + log.warn("Could not process message: queue full"); + } else { + log.error("Error while processing message from peer " + getPeerInfoString() + "state " + this.state); + channel.close(); + } + } + + @Override + public String toString() { + return getPeerInfoString(); + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + if (e.getMessage() instanceof List) { + @SuppressWarnings("Unchecked") + List msglist = (List) e.getMessage(); + for (BGPMessage pm : msglist) { + // Do the actual packet processing + state.processBGPMessage(this, pm); + } + } else { + state.processBGPMessage(this, (BGPMessage) e.getMessage()); + } + } + + // ************************* + // Channel utility methods + // ************************* + /** + * Set handshake status. + * + * @param handshakeComplete handshake complete status + */ + public void setHandshakeComplete(boolean handshakeComplete) { + this.state.setHandshakeComplete(handshakeComplete); + } + + /** + * Is this a state in which the handshake has completed? + * + * @return true if the handshake is complete + */ + public boolean isHandshakeComplete() { + return state.isHandshakeComplete(); + } + + /** + * To handle the BGP message. + * + * @param m BGP message + */ + private void dispatchMessage(BGPMessage m) throws BGPParseException { + bgpPacketStats.addInPacket(); + bgpControllerImpl.processBGPPacket(thisbgpId, m); + } + + /** + * Return a string describing this peer based on the already available information (ip address and/or remote + * socket). + * + * @return display string + */ + private String getPeerInfoString() { + if (bgpPeer != null) { + return bgpPeer.toString(); + } + String channelString; + if (channel == null || channel.getRemoteAddress() == null) { + channelString = "?"; + } else { + channelString = channel.getRemoteAddress().toString(); + } + String bgpIpString; + // TODO: implement functionality to get bgp id string + bgpIpString = "?"; + return String.format("[%s BGP-IP[%s]]", channelString, bgpIpString); + } + + /** + * Update the channels state. Only called from the state machine. TODO: enforce restricted state transitions + * + * @param state + */ + private void setState(ChannelState state) { + this.state = state; + } + + /** + * get packet statistics. + * + * @return packet statistics + */ + public BGPPacketStatsImpl getBgpPacketStats() { + return bgpPacketStats; + } + + /** + * Send handshake open message to the peer. + * + * @throws IOException ,BGPParseException + */ + private void sendHandshakeOpenMessage() throws IOException, BGPParseException { + // TODO: send open message. + + } + + /** + * Send keep alive message. + * + * @throws IOException when channel is disconnected + * @throws BGPParseException while building keep alive message + */ + synchronized void sendKeepAliveMessage() throws IOException, BGPParseException { + + // TODO: send keep alive message. + } + + /** + * Send notification and close channel with peer. + */ + private void sendErrNotificationAndCloseChannel() { + // TODO: send notification + channel.close(); + } + + /** + * Process unknown BGP message received. + * + * @throws BGPParseException when received invalid message + */ + public void processUnknownMsg() throws BGPParseException { + log.debug("UNKNOWN message received"); + Date now = null; + if (bgpPacketStats.wrongPacketCount() == 0) { + now = new Date(); + bgpPacketStats.setTime(now.getTime()); + bgpPacketStats.addWrongPacket(); + sendErrNotificationAndCloseChannel(); + } + if (bgpPacketStats.wrongPacketCount() > 1) { + Date lastest = new Date(); + bgpPacketStats.addWrongPacket(); + // converting to seconds + if (((lastest.getTime() - bgpPacketStats.getTime()) / 1000) > 60) { + now = lastest; + bgpPacketStats.setTime(now.getTime()); + bgpPacketStats.resetWrongPacket(); + bgpPacketStats.addWrongPacket(); + } else if (((int) (lastest.getTime() - now.getTime()) / 1000) < 60) { + if (MAX_WRONG_COUNT_PACKET <= bgpPacketStats.wrongPacketCount()) { + // reset once wrong packet count reaches MAX_WRONG_COUNT_PACKET + bgpPacketStats.resetWrongPacket(); + // max wrong packets received send error message and close the session + sendErrNotificationAndCloseChannel(); + } + } + } + } + + /** + * Open message validation. + * + * @param h channel handler + * @return true if validation succeed, otherwise false + * @throws BGPParseException when received invalid message + */ + public boolean openMsgValidation(BGPChannelHandler h) throws BGPParseException { + // TODO: Open message validation. + return true; } -} \ No newline at end of file +} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java index 95eafdbc..d8378e31 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java @@ -17,16 +17,24 @@ package org.onosproject.bgp.controller.impl; import static org.onlab.util.Tools.groupedThreads; + +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.IpAddress; import org.onosproject.bgp.controller.BGPCfg; import org.onosproject.bgp.controller.BGPController; import org.onosproject.bgp.controller.BGPId; +import org.onosproject.bgp.controller.BGPPacketStats; +import org.onosproject.bgp.controller.BGPPeer; import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.protocol.BGPVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +50,10 @@ public class BGPControllerImpl implements BGPController { private final ExecutorService executorBarrier = Executors.newFixedThreadPool(4, groupedThreads("onos/bgp", - "event-barrier-%d")); + "event-barrier-%d")); + protected ConcurrentHashMap connectedPeers = new ConcurrentHashMap(); + protected BGPPeerManager peerManager = new BGPPeerManager(); final Controller ctrl = new Controller(this); private BGPConfig bgpconfig = new BGPConfig(); @@ -57,10 +67,21 @@ public class BGPControllerImpl implements BGPController { @Deactivate public void deactivate() { // Close all connected peers + closeConnectedPeers(); this.ctrl.stop(); log.info("Stopped"); } + @Override + public Iterable getPeers() { + return this.connectedPeers.values(); + } + + @Override + public BGPPeer getPeer(BGPId bgpId) { + return this.connectedPeers.get(bgpId); + } + @Override public void writeMsg(BGPId bgpId, BGPMessage msg) { // TODO: Send message @@ -88,17 +109,167 @@ public class BGPControllerImpl implements BGPController { } } + @Override + public void closeConnectedPeers() { + BGPPeer bgpPeer; + for (BGPId id : this.connectedPeers.keySet()) { + bgpPeer = getPeer(id); + bgpPeer.disconnectPeer(); + } + } + /** - * Get controller instance. - * - * @return ctrl the controller. + * Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which + * they are. */ + public class BGPPeerManager { + + private final Logger log = LoggerFactory.getLogger(BGPPeerManager.class); + private final Lock peerLock = new ReentrantLock(); + + /** + * Add a BGP peer that has just connected to the system. + * + * @param bgpId the id of bgp peer to add + * @param bgpPeer the actual bgp peer object. + * @return true if added, false otherwise. + */ + public boolean addConnectedPeer(BGPId bgpId, BGPPeer bgpPeer) { + + if (connectedPeers.get(bgpId) != null) { + this.log.error("Trying to add connectedPeer but found previous " + "value for bgp ip: {}", + bgpId.toString()); + return false; + } else { + this.log.debug("Added Peer {}", bgpId.toString()); + connectedPeers.put(bgpId, bgpPeer); + return true; + } + } + + /** + * Checks if the activation for this bgp peer is valid. + * + * @param bgpId the id of bgp peer to check + * @return true if valid, false otherwise + */ + public boolean isPeerConnected(BGPId bgpId) { + if (connectedPeers.get(bgpId) == null) { + this.log.error("Trying to activate peer but is not in " + "connected peer: bgpIp {}. Aborting ..", + bgpId.toString()); + return false; + } + + return true; + } + + /** + * Checks if the activation for this bgp peer is valid. + * + * @param routerid the routerid of bgp peer to check + * @return true if valid, false otherwise + */ + public boolean isPeerConnected(String routerid) { + + final BGPId bgpId; + bgpId = BGPId.bgpId(IpAddress.valueOf(routerid)); + + if (connectedPeers.get(bgpId) != null) { + this.log.info("Peer connection exist "); + return true; + } + this.log.info("Initiate connect request to " + "peer: bgpIp {}", bgpId.toString()); + + return false; + } + + /** + * Clear all state in controller peer maps for a bgp peer that has + * disconnected from the local controller. + * + * @param bgpId the id of bgp peer to remove. + */ + public void removeConnectedPeer(BGPId bgpId) { + connectedPeers.remove(bgpId); + } + + /** + * Clear all state in controller peer maps for a bgp peer that has + * disconnected from the local controller. + * + * @param routerid the router id of bgp peer to remove. + */ + public void removeConnectedPeer(String routerid) { + final BGPId bgpId; + + bgpId = BGPId.bgpId(IpAddress.valueOf(routerid)); + + connectedPeers.remove(bgpId); + } + + /** + * Gets bgp peer for connected peer map. + * + * @param routerid router id + * @return peer if available, null otherwise + */ + public BGPPeer getPeer(String routerid) { + final BGPId bgpId; + bgpId = BGPId.bgpId(IpAddress.valueOf(routerid)); + + return connectedPeers.get(bgpId); + } + + /** + * Gets bgp peer instance. + * + * @param bgpId bgp identifier. + * @param pv bgp version. + * @param pktStats packet statistics. + * @return BGPPeer peer instance. + */ + public BGPPeer getBGPPeerInstance(BGPId bgpId, BGPVersion pv, BGPPacketStats pktStats) { + BGPPeer bgpPeer = new BGPPeerImpl(); + bgpPeer.init(bgpId, pv, pktStats); + return bgpPeer; + } + + } + + /** + * Gets controller instance. + * + * @return Controller instance. + */ public Controller getController() { return ctrl; } + /** + * Gets connected peers. + * + * @return connectedPeers from connected Peers Map. + */ + public ConcurrentHashMap getConnectedPeers() { + return connectedPeers; + } + + /** + * Gets peer manager. + * + * @return peerManager. + */ + public BGPPeerManager getPeerManager() { + return peerManager; + } + @Override public BGPCfg getConfig() { return this.bgpconfig; } + + @Override + public int getBGPConnNumber() { + return connectedPeers.size(); + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java new file mode 100755 index 00000000..1c95804a --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java @@ -0,0 +1,72 @@ +/* + * 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.bgp.controller.impl; + +import java.util.Timer; +import java.util.TimerTask; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implement sending keepalive message to connected peer periodically based on negotiated holdtime. + */ +public class BGPKeepAliveTimer { + + private Timer keepAliveTimer; + private BGPChannelHandler handler; + private static final Logger log = LoggerFactory.getLogger(BGPKeepAliveTimer.class); + + /** + * Gets keepalive timer object. + * + * @return keepAliveTimer keepalive timer. + */ + public Timer getKeepAliveTimer() { + return keepAliveTimer; + } + + /** + * Initialize timer to send keepalive message periodically. + * + * @param h channel handler + * @param seconds time interval. + */ + public BGPKeepAliveTimer(BGPChannelHandler h, int seconds) { + this.handler = h; + this.keepAliveTimer = new Timer(); + this.keepAliveTimer.schedule(new SendKeepAlive(), 0, seconds * 1000); + } + + /** + * Send keepalive message to connected peer on schedule. + */ + class SendKeepAlive extends TimerTask { + @Override + public void run() { + log.debug("Sending periodic KeepAlive"); + + try { + // Send keep alive message + handler.sendKeepAliveMessage(); + handler.getBgpPacketStats().addOutPacket(); + } catch (Exception e) { + log.info("Exception occured while sending keepAlive message" + e.toString()); + } + } + } +} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java index 41407dc4..09f4d452 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java @@ -43,8 +43,7 @@ public class BGPPacketStatsImpl implements BGPPacketStats { /** * Get the outgoing packet count number. * - * @return - * packet count + * @return packet count */ public int outPacketCount() { return outPacketCount; @@ -53,8 +52,7 @@ public class BGPPacketStatsImpl implements BGPPacketStats { /** * Get the incoming packet count number. * - * @return - * packet count + * @return packet count */ public int inPacketCount() { return inPacketCount; @@ -63,8 +61,7 @@ public class BGPPacketStatsImpl implements BGPPacketStats { /** * Get the wrong packet count number. * - * @return - * packet count + * @return packet count */ public int wrongPacketCount() { return wrongPacketCount; @@ -110,8 +107,7 @@ public class BGPPacketStatsImpl implements BGPPacketStats { /** * Get the time. * - * @return - * time + * @return time */ public long getTime() { return this.time; diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java new file mode 100755 index 00000000..212b24d3 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java @@ -0,0 +1,191 @@ +/* + * 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.bgp.controller.impl; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; + +import org.jboss.netty.channel.Channel; +import org.onlab.packet.IpAddress; +import org.onosproject.bgp.controller.BGPId; +import org.onosproject.bgp.controller.BGPPacketStats; +import org.onosproject.bgp.controller.BGPPeer; +import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.protocol.BGPVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB . + */ +public class BGPPeerImpl implements BGPPeer { + + protected final Logger log = LoggerFactory.getLogger(BGPPeerImpl.class); + + private static final String SHUTDOWN_MSG = "Worker has already been shutdown"; + + private Channel channel; + protected String channelId; + private boolean connected; + protected boolean isHandShakeComplete = false; + public BGPSessionInfo sessionInfo; + private BGPPacketStatsImpl pktStats; + + @Override + public void init(BGPId bgpId, BGPVersion bgpVersion, BGPPacketStats pktStats) { + this.sessionInfo.setRemoteBgpId(bgpId); + this.sessionInfo.setRemoteBgpVersion(bgpVersion); + this.pktStats = (BGPPacketStatsImpl) pktStats; + this.sessionInfo = new BGPSessionInfo(); + } + + // ************************ + // Channel related + // ************************ + + @Override + public final void disconnectPeer() { + this.channel.close(); + } + + @Override + public final void sendMessage(BGPMessage m) { + log.debug("Sending message to {}", channel.getRemoteAddress()); + try { + channel.write(Collections.singletonList(m)); + this.pktStats.addOutPacket(); + } catch (RejectedExecutionException e) { + log.warn(e.getMessage()); + if (!e.getMessage().contains(SHUTDOWN_MSG)) { + throw e; + } + } + } + + @Override + public final void sendMessage(List msgs) { + try { + channel.write(msgs); + this.pktStats.addOutPacket(msgs.size()); + } catch (RejectedExecutionException e) { + log.warn(e.getMessage()); + if (!e.getMessage().contains(SHUTDOWN_MSG)) { + throw e; + } + } + } + + @Override + public final boolean isConnected() { + return this.connected; + } + + @Override + public final void setConnected(boolean connected) { + this.connected = connected; + }; + + @Override + public final void setChannel(Channel channel) { + this.channel = channel; + final SocketAddress address = channel.getRemoteAddress(); + if (address instanceof InetSocketAddress) { + final InetSocketAddress inetAddress = (InetSocketAddress) address; + final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress()); + if (ipAddress.isIp4()) { + channelId = ipAddress.toString() + ':' + inetAddress.getPort(); + } else { + channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort(); + } + } + }; + + @Override + public final Channel getChannel() { + return this.channel; + }; + + @Override + public String channelId() { + return channelId; + } + + // ************************ + // BGP Peer features related + // ************************ + + @Override + public final BGPId getBGPId() { + return this.sessionInfo.getRemoteBgpId(); + }; + + @Override + public final String getStringId() { + return this.sessionInfo.getRemoteBgpId().toString(); + } + + @Override + public final void setBgpPeerVersion(BGPVersion peerVersion) { + this.sessionInfo.setRemoteBgpVersion(peerVersion); + } + + @Override + public void setBgpPeerASNum(short peerASNum) { + this.sessionInfo.setRemoteBgpASNum(peerASNum); + } + + @Override + public void setBgpPeerHoldTime(short peerHoldTime) { + this.sessionInfo.setRemoteBgpHoldTime(peerHoldTime); + } + + @Override + public void setBgpPeerIdentifier(int peerIdentifier) { + this.sessionInfo.setRemoteBgpIdentifier(peerIdentifier); + } + + @Override + public int getBgpPeerIdentifier() { + return this.sessionInfo.getRemoteBgpIdentifier(); + } + + @Override + public int getNegotiatedHoldTime() { + return this.sessionInfo.getNegotiatedholdTime(); + } + + @Override + public void setNegotiatedHoldTime(short negotiatedHoldTime) { + this.sessionInfo.setNegotiatedholdTime(negotiatedHoldTime); + } + + @Override + public boolean isHandshakeComplete() { + return isHandShakeComplete; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues().add("channel", channelId()) + .add("bgpId", getBGPId()).toString(); + } +} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java new file mode 100755 index 00000000..207d7831 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPSessionInfo.java @@ -0,0 +1,149 @@ +/* + * 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.bgp.controller.impl; + +import org.onosproject.bgp.controller.BGPId; +import org.onosproject.bgpio.protocol.BGPVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class maintains BGP peer session info. + */ +public class BGPSessionInfo { + + protected final Logger log = LoggerFactory.getLogger(BGPSessionInfo.class); + private BGPId remoteBgpId; + private BGPVersion remoteBgpVersion; + private short remoteBgpASNum; + private short remoteBgpholdTime; + private int remoteBgpIdentifier; + private short negotiatedholdTime; + + /** + * Gets the negotiated hold time for the session. + * + * @return negotiated hold time. + */ + public short getNegotiatedholdTime() { + return negotiatedholdTime; + } + + /** + * Sets the negotiated hold time for the session. + * + * @param negotiatedholdTime negotiated hold time. + */ + public void setNegotiatedholdTime(short negotiatedholdTime) { + this.negotiatedholdTime = negotiatedholdTime; + } + + /** + * Gets the BGP ID of BGP peer. + * + * @return bgp ID. + */ + public BGPId getRemoteBgpId() { + return remoteBgpId; + } + + /** + * Sets the BGP ID of bgp peer. + * + * @param bgpId BGP ID to set. + */ + public void setRemoteBgpId(BGPId bgpId) { + log.debug("Remote BGP ID {}", bgpId); + this.remoteBgpId = bgpId; + } + + /** + * Gets the BGP version of peer. + * + * @return bgp version. + */ + public BGPVersion getRemoteBgpVersion() { + return remoteBgpVersion; + } + + /** + * Sets the BGP version for this bgp peer. + * + * @param bgpVersion bgp version to set. + */ + public void setRemoteBgpVersion(BGPVersion bgpVersion) { + log.debug("Remote BGP version {}", bgpVersion); + this.remoteBgpVersion = bgpVersion; + } + + /** + * Gets the BGP remote bgp AS number. + * + * @return remoteBgpASNum peer AS number. + */ + public short getRemoteBgpASNum() { + return remoteBgpASNum; + } + + /** + * Sets the AS Number for this bgp peer. + * + * @param bgpASNum the autonomous system number value to set. + */ + public void setRemoteBgpASNum(short bgpASNum) { + log.debug("Remote BGP AS number {}", bgpASNum); + this.remoteBgpASNum = bgpASNum; + } + + /** + * Gets the BGP peer hold time. + * + * @return bgp hold time. + */ + public short getRemoteBgpHoldTime() { + return remoteBgpholdTime; + } + + /** + * Sets the hold time for this bgp peer. + * + * @param holdTime the hold timer value to set. + */ + public void setRemoteBgpHoldTime(short holdTime) { + log.debug("Remote BGP HoldTime {}", holdTime); + this.remoteBgpholdTime = holdTime; + } + + /** + * Gets the BGP version for this bgp peer. + * + * @return bgp identifier. + */ + public int getRemoteBgpIdentifier() { + return remoteBgpIdentifier; + } + + /** + * Sets the peer identifier value. + * + * @param bgpIdentifier the bgp peer identifier value. + */ + public void setRemoteBgpIdentifier(int bgpIdentifier) { + log.debug("Remote BGP Identifier {}", bgpIdentifier); + this.remoteBgpIdentifier = bgpIdentifier; + } +} -- cgit 1.2.3-korg