diff options
Diffstat (limited to 'framework/src/onos/apps/routing')
37 files changed, 0 insertions, 10020 deletions
diff --git a/framework/src/onos/apps/routing/pom.xml b/framework/src/onos/apps/routing/pom.xml deleted file mode 100644 index c4562106..00000000 --- a/framework/src/onos/apps/routing/pom.xml +++ /dev/null @@ -1,111 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ 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. - --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <parent> - <artifactId>onos-apps</artifactId> - <groupId>org.onosproject</groupId> - <version>1.4.0-rc1</version> - <relativePath>../pom.xml</relativePath> - </parent> - <modelVersion>4.0.0</modelVersion> - - <artifactId>onos-app-routing</artifactId> - - <packaging>bundle</packaging> - <description>Libraries for routing applications</description> - - <dependencies> - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-app-routing-api</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-cli</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-thirdparty</artifactId> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-misc</artifactId> - </dependency> - - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - </dependency> - - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - </dependency> - - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - </dependency> - - <dependency> - <groupId>io.netty</groupId> - <artifactId>netty</artifactId> - <version>3.9.0.Final</version> - </dependency> - - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.compendium</artifactId> - </dependency> - - <dependency> - <groupId>org.apache.karaf.shell</groupId> - <artifactId>org.apache.karaf.shell.console</artifactId> - </dependency> - - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.core</artifactId> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-junit</artifactId> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.easymock</groupId> - <artifactId>easymock</artifactId> - <scope>test</scope> - </dependency> - - </dependencies> - -</project> diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java deleted file mode 100644 index 89060ad5..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpConstants.java +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -/** - * BGP related constants. - */ -public final class BgpConstants { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private BgpConstants() { - } - - /** BGP port number (RFC 4271). */ - public static final int BGP_PORT = 179; - - /** BGP version. */ - public static final int BGP_VERSION = 4; - - /** BGP OPEN message type. */ - public static final int BGP_TYPE_OPEN = 1; - - /** BGP UPDATE message type. */ - public static final int BGP_TYPE_UPDATE = 2; - - /** BGP NOTIFICATION message type. */ - public static final int BGP_TYPE_NOTIFICATION = 3; - - /** BGP KEEPALIVE message type. */ - public static final int BGP_TYPE_KEEPALIVE = 4; - - /** BGP Header Marker field length. */ - public static final int BGP_HEADER_MARKER_LENGTH = 16; - - /** BGP Header length. */ - public static final int BGP_HEADER_LENGTH = 19; - - /** BGP message maximum length. */ - public static final int BGP_MESSAGE_MAX_LENGTH = 4096; - - /** BGP OPEN message minimum length (BGP Header included). */ - public static final int BGP_OPEN_MIN_LENGTH = 29; - - /** BGP UPDATE message minimum length (BGP Header included). */ - public static final int BGP_UPDATE_MIN_LENGTH = 23; - - /** BGP NOTIFICATION message minimum length (BGP Header included). */ - public static final int BGP_NOTIFICATION_MIN_LENGTH = 21; - - /** BGP KEEPALIVE message expected length (BGP Header included). */ - public static final int BGP_KEEPALIVE_EXPECTED_LENGTH = 19; - - /** BGP KEEPALIVE messages transmitted per Hold interval. */ - public static final int BGP_KEEPALIVE_PER_HOLD_INTERVAL = 3; - - /** BGP KEEPALIVE messages minimum Holdtime (in seconds). */ - public static final int BGP_KEEPALIVE_MIN_HOLDTIME = 3; - - /** BGP KEEPALIVE messages minimum transmission interval (in seconds). */ - public static final int BGP_KEEPALIVE_MIN_INTERVAL = 1; - - /** BGP AS 0 (zero) value. See draft-ietf-idr-as0-06.txt Internet Draft. */ - public static final long BGP_AS_0 = 0; - - /** - * BGP OPEN related constants. - */ - public static final class Open { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private Open() { - } - - /** - * BGP OPEN: Optional Parameters related constants. - */ - public static final class OptionalParameters { - } - - /** - * BGP OPEN: Capabilities related constants (RFC 5492). - */ - public static final class Capabilities { - /** BGP OPEN Optional Parameter Type: Capabilities. */ - public static final int TYPE = 2; - - /** BGP OPEN Optional Parameter minimum length. */ - public static final int MIN_LENGTH = 2; - - /** - * BGP OPEN: Multiprotocol Extensions Capabilities (RFC 4760). - */ - public static final class MultiprotocolExtensions { - /** BGP OPEN Multiprotocol Extensions code. */ - public static final int CODE = 1; - - /** BGP OPEN Multiprotocol Extensions length. */ - public static final int LENGTH = 4; - - /** BGP OPEN Multiprotocol Extensions AFI: IPv4. */ - public static final int AFI_IPV4 = 1; - - /** BGP OPEN Multiprotocol Extensions AFI: IPv6. */ - public static final int AFI_IPV6 = 2; - - /** BGP OPEN Multiprotocol Extensions SAFI: unicast. */ - public static final int SAFI_UNICAST = 1; - - /** BGP OPEN Multiprotocol Extensions SAFI: multicast. */ - public static final int SAFI_MULTICAST = 2; - } - - /** - * BGP OPEN: Support for 4-octet AS Number Capability (RFC 6793). - */ - public static final class As4Octet { - /** BGP OPEN Support for 4-octet AS Number Capability code. */ - public static final int CODE = 65; - - /** BGP OPEN 4-octet AS Number Capability length. */ - public static final int LENGTH = 4; - } - } - } - - /** - * BGP UPDATE related constants. - */ - public static final class Update { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private Update() { - } - - /** BGP AS length. */ - public static final int AS_LENGTH = 2; - - /** BGP 4 Octet AS length (RFC 6793). */ - public static final int AS_4OCTET_LENGTH = 4; - - /** - * BGP UPDATE: ORIGIN related constants. - */ - public static final class Origin { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private Origin() { - } - - /** BGP UPDATE Attributes Type Code ORIGIN. */ - public static final int TYPE = 1; - - /** BGP UPDATE Attributes Type Code ORIGIN length. */ - public static final int LENGTH = 1; - - /** BGP UPDATE ORIGIN: IGP. */ - public static final int IGP = 0; - - /** BGP UPDATE ORIGIN: EGP. */ - public static final int EGP = 1; - - /** BGP UPDATE ORIGIN: INCOMPLETE. */ - public static final int INCOMPLETE = 2; - - /** - * Gets the BGP UPDATE origin type as a string. - * - * @param type the BGP UPDATE origin type - * @return the BGP UPDATE origin type as a string - */ - public static String typeToString(int type) { - String typeString = "UNKNOWN"; - - switch (type) { - case IGP: - typeString = "IGP"; - break; - case EGP: - typeString = "EGP"; - break; - case INCOMPLETE: - typeString = "INCOMPLETE"; - break; - default: - break; - } - return typeString; - } - } - - /** - * BGP UPDATE: AS_PATH related constants. - */ - public static final class AsPath { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private AsPath() { - } - - /** BGP UPDATE Attributes Type Code AS_PATH. */ - public static final int TYPE = 2; - - /** BGP UPDATE AS_PATH Type: AS_SET. */ - public static final int AS_SET = 1; - - /** BGP UPDATE AS_PATH Type: AS_SEQUENCE. */ - public static final int AS_SEQUENCE = 2; - - /** BGP UPDATE AS_PATH Type: AS_CONFED_SEQUENCE. */ - public static final int AS_CONFED_SEQUENCE = 3; - - /** BGP UPDATE AS_PATH Type: AS_CONFED_SET. */ - public static final int AS_CONFED_SET = 4; - - /** - * Gets the BGP AS_PATH type as a string. - * - * @param type the BGP AS_PATH type - * @return the BGP AS_PATH type as a string - */ - public static String typeToString(int type) { - String typeString = "UNKNOWN"; - - switch (type) { - case AS_SET: - typeString = "AS_SET"; - break; - case AS_SEQUENCE: - typeString = "AS_SEQUENCE"; - break; - case AS_CONFED_SEQUENCE: - typeString = "AS_CONFED_SEQUENCE"; - break; - case AS_CONFED_SET: - typeString = "AS_CONFED_SET"; - break; - default: - break; - } - return typeString; - } - } - - /** - * BGP UPDATE: NEXT_HOP related constants. - */ - public static final class NextHop { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private NextHop() { - } - - /** BGP UPDATE Attributes Type Code NEXT_HOP. */ - public static final int TYPE = 3; - - /** BGP UPDATE Attributes Type Code NEXT_HOP length. */ - public static final int LENGTH = 4; - } - - /** - * BGP UPDATE: MULTI_EXIT_DISC related constants. - */ - public static final class MultiExitDisc { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private MultiExitDisc() { - } - - /** BGP UPDATE Attributes Type Code MULTI_EXIT_DISC. */ - public static final int TYPE = 4; - - /** BGP UPDATE Attributes Type Code MULTI_EXIT_DISC length. */ - public static final int LENGTH = 4; - - /** BGP UPDATE Attributes lowest MULTI_EXIT_DISC value. */ - public static final int LOWEST_MULTI_EXIT_DISC = 0; - } - - /** - * BGP UPDATE: LOCAL_PREF related constants. - */ - public static final class LocalPref { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private LocalPref() { - } - - /** BGP UPDATE Attributes Type Code LOCAL_PREF. */ - public static final int TYPE = 5; - - /** BGP UPDATE Attributes Type Code LOCAL_PREF length. */ - public static final int LENGTH = 4; - } - - /** - * BGP UPDATE: ATOMIC_AGGREGATE related constants. - */ - public static final class AtomicAggregate { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private AtomicAggregate() { - } - - /** BGP UPDATE Attributes Type Code ATOMIC_AGGREGATE. */ - public static final int TYPE = 6; - - /** BGP UPDATE Attributes Type Code ATOMIC_AGGREGATE length. */ - public static final int LENGTH = 0; - } - - /** - * BGP UPDATE: AGGREGATOR related constants. - */ - public static final class Aggregator { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private Aggregator() { - } - - /** BGP UPDATE Attributes Type Code AGGREGATOR. */ - public static final int TYPE = 7; - - /** BGP UPDATE Attributes Type Code AGGREGATOR length: 2 octet AS. */ - public static final int AS2_LENGTH = 6; - - /** BGP UPDATE Attributes Type Code AGGREGATOR length: 4 octet AS. */ - public static final int AS4_LENGTH = 8; - } - - /** - * BGP UPDATE: MP_REACH_NLRI related constants. - */ - public static final class MpReachNlri { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private MpReachNlri() { - } - - /** BGP UPDATE Attributes Type Code MP_REACH_NLRI. */ - public static final int TYPE = 14; - - /** BGP UPDATE Attributes Type Code MP_REACH_NLRI min length. */ - public static final int MIN_LENGTH = 5; - } - - /** - * BGP UPDATE: MP_UNREACH_NLRI related constants. - */ - public static final class MpUnreachNlri { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private MpUnreachNlri() { - } - - /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI. */ - public static final int TYPE = 15; - - /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI min length. */ - public static final int MIN_LENGTH = 3; - } - } - - /** - * BGP NOTIFICATION related constants. - */ - public static final class Notifications { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private Notifications() { - } - - /** - * BGP NOTIFICATION: Message Header Error constants. - */ - public static final class MessageHeaderError { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private MessageHeaderError() { - } - - /** Message Header Error code. */ - public static final int ERROR_CODE = 1; - - /** Message Header Error subcode: Connection Not Synchronized. */ - public static final int CONNECTION_NOT_SYNCHRONIZED = 1; - - /** Message Header Error subcode: Bad Message Length. */ - public static final int BAD_MESSAGE_LENGTH = 2; - - /** Message Header Error subcode: Bad Message Type. */ - public static final int BAD_MESSAGE_TYPE = 3; - } - - /** - * BGP NOTIFICATION: OPEN Message Error constants. - */ - public static final class OpenMessageError { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private OpenMessageError() { - } - - /** OPEN Message Error code. */ - public static final int ERROR_CODE = 2; - - /** OPEN Message Error subcode: Unsupported Version Number. */ - public static final int UNSUPPORTED_VERSION_NUMBER = 1; - - /** OPEN Message Error subcode: Bad PEER AS. */ - public static final int BAD_PEER_AS = 2; - - /** OPEN Message Error subcode: Unacceptable Hold Time. */ - public static final int UNACCEPTABLE_HOLD_TIME = 6; - } - - /** - * BGP NOTIFICATION: UPDATE Message Error constants. - */ - public static final class UpdateMessageError { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private UpdateMessageError() { - } - - /** UPDATE Message Error code. */ - public static final int ERROR_CODE = 3; - - /** UPDATE Message Error subcode: Malformed Attribute List. */ - public static final int MALFORMED_ATTRIBUTE_LIST = 1; - - /** UPDATE Message Error subcode: Unrecognized Well-known Attribute. */ - public static final int UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE = 2; - - /** UPDATE Message Error subcode: Missing Well-known Attribute. */ - public static final int MISSING_WELL_KNOWN_ATTRIBUTE = 3; - - /** UPDATE Message Error subcode: Attribute Flags Error. */ - public static final int ATTRIBUTE_FLAGS_ERROR = 4; - - /** UPDATE Message Error subcode: Attribute Length Error. */ - public static final int ATTRIBUTE_LENGTH_ERROR = 5; - - /** UPDATE Message Error subcode: Invalid ORIGIN Attribute. */ - public static final int INVALID_ORIGIN_ATTRIBUTE = 6; - - /** UPDATE Message Error subcode: Invalid NEXT_HOP Attribute. */ - public static final int INVALID_NEXT_HOP_ATTRIBUTE = 8; - - /** UPDATE Message Error subcode: Optional Attribute Error. Unused. */ - public static final int OPTIONAL_ATTRIBUTE_ERROR = 9; - - /** UPDATE Message Error subcode: Invalid Network Field. */ - public static final int INVALID_NETWORK_FIELD = 10; - - /** UPDATE Message Error subcode: Malformed AS_PATH. */ - public static final int MALFORMED_AS_PATH = 11; - } - - /** - * BGP NOTIFICATION: Hold Timer Expired constants. - */ - public static final class HoldTimerExpired { - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private HoldTimerExpired() { - } - - /** Hold Timer Expired code. */ - public static final int ERROR_CODE = 4; - } - - /** BGP NOTIFICATION message Error subcode: Unspecific. */ - public static final int ERROR_SUBCODE_UNSPECIFIC = 0; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java deleted file mode 100644 index 98ec4a45..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpFrameDecoder.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class for handling the decoding of the BGP messages. - */ -class BgpFrameDecoder extends FrameDecoder { - private static final Logger log = - LoggerFactory.getLogger(BgpFrameDecoder.class); - - private final BgpSession bgpSession; - - /** - * Constructor for a given BGP Session. - * - * @param bgpSession the BGP session state to use. - */ - BgpFrameDecoder(BgpSession bgpSession) { - this.bgpSession = bgpSession; - } - - @Override - protected Object decode(ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { - // - // NOTE: If we close the channel during the decoding, we might still - // see some incoming messages while the channel closing is completed. - // - if (bgpSession.isClosed()) { - return null; - } - - log.trace("BGP Peer: decode(): remoteAddr = {} localAddr = {} " + - "messageSize = {}", - ctx.getChannel().getRemoteAddress(), - ctx.getChannel().getLocalAddress(), - buf.readableBytes()); - - // Test for minimum length of the BGP message - if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) { - // No enough data received - return null; - } - - // - // Mark the current buffer position in case we haven't received - // the whole message. - // - buf.markReaderIndex(); - - // - // Read and check the BGP message Marker field: it must be all ones - // (See RFC 4271, Section 4.1) - // - byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH]; - buf.readBytes(marker); - for (int i = 0; i < marker.length; i++) { - if (marker[i] != (byte) 0xff) { - log.debug("BGP RX Error: invalid marker {} at position {}", - marker[i], i); - // - // ERROR: Connection Not Synchronized - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE; - int errorSubcode = - BgpConstants.Notifications.MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, - errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return null; - } - } - - // - // Read and check the BGP message Length field - // - int length = buf.readUnsignedShort(); - if ((length < BgpConstants.BGP_HEADER_LENGTH) || - (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) { - log.debug("BGP RX Error: invalid Length field {}. " + - "Must be between {} and {}", - length, - BgpConstants.BGP_HEADER_LENGTH, - BgpConstants.BGP_MESSAGE_MAX_LENGTH); - // - // ERROR: Bad Message Length - // - // Send NOTIFICATION and close the connection - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotificationBadMessageLength(length); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return null; - } - - // - // Test whether the rest of the message is received: - // So far we have read the Marker (16 octets) and the - // Length (2 octets) fields. - // - int remainingMessageLen = - length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2; - if (buf.readableBytes() < remainingMessageLen) { - // No enough data received - buf.resetReaderIndex(); - return null; - } - - // - // Read the BGP message Type field, and process based on that type - // - int type = buf.readUnsignedByte(); - remainingMessageLen--; // Adjust after reading the type - ChannelBuffer message = buf.readBytes(remainingMessageLen); - - // - // Process the remaining of the message based on the message type - // - switch (type) { - case BgpConstants.BGP_TYPE_OPEN: - BgpOpen.processBgpOpen(bgpSession, ctx, message); - break; - case BgpConstants.BGP_TYPE_UPDATE: - BgpUpdate.processBgpUpdate(bgpSession, ctx, message); - break; - case BgpConstants.BGP_TYPE_NOTIFICATION: - BgpNotification.processBgpNotification(bgpSession, ctx, message); - break; - case BgpConstants.BGP_TYPE_KEEPALIVE: - BgpKeepalive.processBgpKeepalive(bgpSession, ctx, message); - break; - default: - // - // ERROR: Bad Message Type - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.MessageHeaderError.BAD_MESSAGE_TYPE; - ChannelBuffer data = ChannelBuffers.buffer(1); - data.writeByte(type); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return null; - } - return null; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java deleted file mode 100644 index ee8fef16..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpInfoService.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.routing.bgp; - -import java.util.Collection; - -/** - * Provides information about BGP peering and routes. - */ -public interface BgpInfoService { - - /** - * Gets the BGP sessions. - * - * @return the BGP sessions - */ - Collection<BgpSession> getBgpSessions(); - - /** - * Gets the selected IPv4 BGP routes among all BGP sessions. - * - * @return the selected IPv4 BGP routes among all BGP sessions - */ - Collection<BgpRouteEntry> getBgpRoutes4(); - - /** - * Gets the selected IPv6 BGP routes among all BGP sessions. - * - * @return the selected IPv6 BGP routes among all BGP sessions - */ - Collection<BgpRouteEntry> getBgpRoutes6(); -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java deleted file mode 100644 index 1d7f5b6d..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpKeepalive.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A class for handling BGP KEEPALIVE messages. - */ -final class BgpKeepalive { - private static final Logger log = - LoggerFactory.getLogger(BgpKeepalive.class); - - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private BgpKeepalive() { - } - - /** - * Processes BGP KEEPALIVE message. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to process - */ - static void processBgpKeepalive(BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message) { - if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH != - BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) { - log.debug("BGP RX KEEPALIVE Error from {}: " + - "Invalid total message length {}. Expected {}", - bgpSession.remoteInfo().address(), - message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH, - BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH); - // - // ERROR: Bad Message Length - // - // Send NOTIFICATION and close the connection - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotificationBadMessageLength( - message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - - // - // Parse the KEEPALIVE message: nothing to do - // - log.trace("BGP RX KEEPALIVE message from {}", - bgpSession.remoteInfo().address()); - - // Start the Session Timeout timer - bgpSession.restartSessionTimeoutTimer(ctx); - } - - /** - * Prepares BGP KEEPALIVE message. - * - * @return the message to transmit (BGP header included) - */ - static ChannelBuffer prepareBgpKeepalive() { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // - // Prepare the KEEPALIVE message payload: nothing to do - // - return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_KEEPALIVE, - message); - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java deleted file mode 100644 index e93362e5..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpMessage.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A class for preparing BGP messages. - */ -final class BgpMessage { - private static final Logger log = - LoggerFactory.getLogger(BgpMessage.class); - - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private BgpMessage() { - } - - /** - * Prepares BGP message. - * - * @param type the BGP message type - * @param payload the message payload to transmit (BGP header excluded) - * @return the message to transmit (BGP header included) - */ - static ChannelBuffer prepareBgpMessage(int type, ChannelBuffer payload) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_HEADER_LENGTH + - payload.readableBytes()); - - // Write the marker - for (int i = 0; i < BgpConstants.BGP_HEADER_MARKER_LENGTH; i++) { - message.writeByte(0xff); - } - - // Write the rest of the BGP header - message.writeShort(BgpConstants.BGP_HEADER_LENGTH + - payload.readableBytes()); - message.writeByte(type); - - // Write the payload - message.writeBytes(payload); - return message; - } - - /** - * An exception indicating a parsing error of the BGP message. - */ - static final class BgpParseException extends Exception { - /** - * Default constructor. - */ - private BgpParseException() { - super(); - } - - /** - * Constructor for a specific exception details message. - * - * @param message the message with the exception details - */ - BgpParseException(String message) { - super(message); - } - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java deleted file mode 100644 index 233f771b..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpNotification.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A class for handling BGP NOTIFICATION messages. - */ -final class BgpNotification { - private static final Logger log = - LoggerFactory.getLogger(BgpNotification.class); - - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private BgpNotification() { - } - - /** - * Processes BGP NOTIFICATION message. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to process - */ - static void processBgpNotification(BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message) { - int minLength = - BgpConstants.BGP_NOTIFICATION_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH; - if (message.readableBytes() < minLength) { - log.debug("BGP RX NOTIFICATION Error from {}: " + - "Message length {} too short. Must be at least {}", - bgpSession.remoteInfo().address(), - message.readableBytes(), minLength); - // - // ERROR: Bad Message Length - // - // NOTE: We do NOT send NOTIFICATION in response to a notification - return; - } - - // - // Parse the NOTIFICATION message - // - int errorCode = message.readUnsignedByte(); - int errorSubcode = message.readUnsignedByte(); - int dataLength = message.readableBytes(); - - log.debug("BGP RX NOTIFICATION message from {}: Error Code {} " + - "Error Subcode {} Data Length {}", - bgpSession.remoteInfo().address(), errorCode, errorSubcode, - dataLength); - - // - // NOTE: If the peer sent a NOTIFICATION, we leave it to the peer to - // close the connection. - // - - // Start the Session Timeout timer - bgpSession.restartSessionTimeoutTimer(ctx); - } - - /** - * Prepares BGP NOTIFICATION message. - * - * @param errorCode the BGP NOTIFICATION Error Code - * @param errorSubcode the BGP NOTIFICATION Error Subcode if applicable, - * otherwise BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC - * @param data the BGP NOTIFICATION Data if applicable, otherwise null - * @return the message to transmit (BGP header included) - */ - static ChannelBuffer prepareBgpNotification(int errorCode, - int errorSubcode, - ChannelBuffer data) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // - // Prepare the NOTIFICATION message payload - // - message.writeByte(errorCode); - message.writeByte(errorSubcode); - if (data != null) { - message.writeBytes(data); - } - return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_NOTIFICATION, - message); - } - - /** - * Prepares BGP NOTIFICATION message: Bad Message Length. - * - * @param length the erroneous Length field - * @return the message to transmit (BGP header included) - */ - static ChannelBuffer prepareBgpNotificationBadMessageLength(int length) { - int errorCode = BgpConstants.Notifications.MessageHeaderError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.MessageHeaderError.BAD_MESSAGE_LENGTH; - ChannelBuffer data = ChannelBuffers.buffer(2); - data.writeShort(length); - - return prepareBgpNotification(errorCode, errorSubcode, data); - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java deleted file mode 100644 index 1ccb6b6b..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpOpen.java +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.onlab.packet.Ip4Address; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A class for handling BGP OPEN messages. - */ -final class BgpOpen { - private static final Logger log = LoggerFactory.getLogger(BgpOpen.class); - - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private BgpOpen() { - } - - /** - * Processes BGP OPEN message. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to process - */ - static void processBgpOpen(BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message) { - int minLength = - BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH; - if (message.readableBytes() < minLength) { - log.debug("BGP RX OPEN Error from {}: " + - "Message length {} too short. Must be at least {}", - bgpSession.remoteInfo().address(), - message.readableBytes(), minLength); - // - // ERROR: Bad Message Length - // - // Send NOTIFICATION and close the connection - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotificationBadMessageLength( - message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - - // - // Parse the OPEN message - // - // Remote BGP version - int remoteBgpVersion = message.readUnsignedByte(); - if (remoteBgpVersion != BgpConstants.BGP_VERSION) { - log.debug("BGP RX OPEN Error from {}: " + - "Unsupported BGP version {}. Should be {}", - bgpSession.remoteInfo().address(), remoteBgpVersion, - BgpConstants.BGP_VERSION); - // - // ERROR: Unsupported Version Number - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNSUPPORTED_VERSION_NUMBER; - ChannelBuffer data = ChannelBuffers.buffer(2); - data.writeShort(BgpConstants.BGP_VERSION); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - bgpSession.remoteInfo().setBgpVersion(remoteBgpVersion); - - // Remote AS number - long remoteAs = message.readUnsignedShort(); - bgpSession.remoteInfo().setAsNumber(remoteAs); - // - // NOTE: Currently, the local AS number is always set to the remote AS. - // This is done, because the peer setup is always iBGP. - // In the future, the local AS number should be configured as part - // of an explicit BGP peering configuration. - // - bgpSession.localInfo().setAsNumber(remoteAs); - - // Remote Hold Time - long remoteHoldtime = message.readUnsignedShort(); - if ((remoteHoldtime != 0) && - (remoteHoldtime < BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME)) { - log.debug("BGP RX OPEN Error from {}: " + - "Unacceptable Hold Time field {}. " + - "Should be 0 or at least {}", - bgpSession.remoteInfo().address(), remoteHoldtime, - BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME); - // - // ERROR: Unacceptable Hold Time - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.OpenMessageError.UNACCEPTABLE_HOLD_TIME; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - bgpSession.remoteInfo().setHoldtime(remoteHoldtime); - // - // NOTE: Currently. the local BGP Holdtime is always set to the remote - // BGP holdtime. - // In the future, the local BGP Holdtime should be configured as part - // of an explicit BGP peering configuration. - // - bgpSession.localInfo().setHoldtime(remoteHoldtime); - - // Remote BGP Identifier - Ip4Address remoteBgpId = - Ip4Address.valueOf((int) message.readUnsignedInt()); - bgpSession.remoteInfo().setBgpId(remoteBgpId); - - // Parse the Optional Parameters - try { - parseOptionalParameters(bgpSession, ctx, message); - } catch (BgpMessage.BgpParseException e) { - // ERROR: Error parsing optional parameters - log.debug("BGP RX OPEN Error from {}: " + - "Exception parsing Optional Parameters: {}", - bgpSession.remoteInfo().address(), e); - // - // ERROR: Invalid Optional Parameters: Unspecific - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - - // - // NOTE: Prepare the BGP OPEN message before the original local AS - // is overwritten by the 4-octet AS number - // - ChannelBuffer txOpenMessage = prepareBgpOpen(bgpSession.localInfo()); - - // - // Use the 4-octet AS number in lieu of the "My AS" field - // See RFC 6793, Section 4.1, second paragraph. - // - if (bgpSession.remoteInfo().as4OctetCapability()) { - long as4Number = bgpSession.remoteInfo().as4Number(); - bgpSession.remoteInfo().setAsNumber(as4Number); - bgpSession.localInfo().setAsNumber(as4Number); - } - - // - // Verify that the AS number is same for all other BGP Sessions - // NOTE: This check applies only for our use-case where all BGP - // sessions are iBGP. - // - for (BgpSession bs : bgpSession.getBgpSessionManager().getBgpSessions()) { - if ((bs.remoteInfo().asNumber() != 0) && - (bgpSession.remoteInfo().asNumber() != - bs.remoteInfo().asNumber())) { - log.debug("BGP RX OPEN Error from {}: Bad Peer AS {}. " + - "Expected {}", - bgpSession.remoteInfo().address(), - bgpSession.remoteInfo().asNumber(), - bs.remoteInfo().asNumber()); - // - // ERROR: Bad Peer AS - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.OpenMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.OpenMessageError.BAD_PEER_AS; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, - errorSubcode, null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - } - - log.debug("BGP RX OPEN message from {}: " + - "BGPv{} AS {} BGP-ID {} Holdtime {}", - bgpSession.remoteInfo().address(), - bgpSession.remoteInfo().bgpVersion(), - bgpSession.remoteInfo().asNumber(), - bgpSession.remoteInfo().bgpId(), - bgpSession.remoteInfo().holdtime()); - - // Send my OPEN followed by KEEPALIVE - ctx.getChannel().write(txOpenMessage); - // - ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive(); - ctx.getChannel().write(txMessage); - - // Start the KEEPALIVE timer - bgpSession.restartKeepaliveTimer(ctx); - - // Start the Session Timeout timer - bgpSession.restartSessionTimeoutTimer(ctx); - } - - /** - * Prepares BGP OPEN message. - * - * @param localInfo the BGP Session local information to use - * @return the message to transmit (BGP header included) - */ - static ChannelBuffer prepareBgpOpen(BgpSessionInfo localInfo) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // - // Prepare the OPEN message payload - // - message.writeByte(localInfo.bgpVersion()); - message.writeShort((int) localInfo.asNumber()); - message.writeShort((int) localInfo.holdtime()); - message.writeInt(localInfo.bgpId().toInt()); - - // Prepare the optional BGP Capabilities - ChannelBuffer capabilitiesMessage = - prepareBgpOpenCapabilities(localInfo); - message.writeByte(capabilitiesMessage.readableBytes()); - message.writeBytes(capabilitiesMessage); - - return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN, - message); - } - - /** - * Parses BGP OPEN Optional Parameters. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to process - * @throws BgpMessage.BgpParseException - */ - private static void parseOptionalParameters(BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // - // Get and verify the Optional Parameters Length - // - int optParamLength = message.readUnsignedByte(); - if (optParamLength > message.readableBytes()) { - // ERROR: Invalid Optional Parameter Length - String errorMsg = "Invalid Optional Parameter Length field " + - optParamLength + ". Remaining Optional Parameters " + - message.readableBytes(); - throw new BgpMessage.BgpParseException(errorMsg); - } - if (optParamLength == 0) { - return; // No Optional Parameters - } - - // - // Parse the Optional Parameters - // - int optParamEnd = message.readerIndex() + optParamLength; - while (message.readerIndex() < optParamEnd) { - int paramType = message.readUnsignedByte(); - if (message.readerIndex() >= optParamEnd) { - // ERROR: Malformed Optional Parameters - String errorMsg = "Malformed Optional Parameters"; - throw new BgpMessage.BgpParseException(errorMsg); - } - int paramLen = message.readUnsignedByte(); - if (message.readerIndex() + paramLen > optParamEnd) { - // ERROR: Malformed Optional Parameters - String errorMsg = "Malformed Optional Parameters"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // - // Extract the Optional Parameter Value based on the Parameter Type - // - switch (paramType) { - case BgpConstants.Open.Capabilities.TYPE: - // Optional Parameter Type: Capabilities - if (paramLen < BgpConstants.Open.Capabilities.MIN_LENGTH) { - // ERROR: Malformed Param Type - String errorMsg = "Malformed Capabilities Optional " - + "Parameter Type " + paramType; - throw new BgpMessage.BgpParseException(errorMsg); - } - int paramEnd = message.readerIndex() + paramLen; - // Parse Capabilities - while (message.readerIndex() < paramEnd) { - if (paramEnd - message.readerIndex() < - BgpConstants.Open.Capabilities.MIN_LENGTH) { - String errorMsg = "Malformed Capabilities"; - throw new BgpMessage.BgpParseException(errorMsg); - } - int capabCode = message.readUnsignedByte(); - int capabLen = message.readUnsignedByte(); - if (message.readerIndex() + capabLen > paramEnd) { - // ERROR: Malformed Capability - String errorMsg = "Malformed Capability instance with " - + "code " + capabCode; - throw new BgpMessage.BgpParseException(errorMsg); - } - - switch (capabCode) { - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE: - // Multiprotocol Extensions Capabilities (RFC 4760) - if (capabLen != BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH) { - // ERROR: Multiprotocol Extension Length Error - String errorMsg = "Multiprotocol Extension Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - // Decode the AFI (2 octets) and SAFI (1 octet) - int afi = message.readUnsignedShort(); - int reserved = message.readUnsignedByte(); - int safi = message.readUnsignedByte(); - log.debug("BGP RX OPEN Capability: AFI = {} SAFI = {}", - afi, safi); - // - // Setup the AFI/SAFI in the BgpSession - // - // NOTE: For now we just copy the remote AFI/SAFI setting - // to the local configuration. - // - if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) { - bgpSession.remoteInfo().setIpv4Unicast(); - bgpSession.localInfo().setIpv4Unicast(); - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) { - bgpSession.remoteInfo().setIpv4Multicast(); - bgpSession.localInfo().setIpv4Multicast(); - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) { - bgpSession.remoteInfo().setIpv6Unicast(); - bgpSession.localInfo().setIpv6Unicast(); - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 && - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) { - bgpSession.remoteInfo().setIpv6Multicast(); - bgpSession.localInfo().setIpv6Multicast(); - } else { - log.debug("BGP RX OPEN Capability: Unknown AFI = {} SAFI = {}", - afi, safi); - } - break; - - case BgpConstants.Open.Capabilities.As4Octet.CODE: - // Support for 4-octet AS Number Capabilities (RFC 6793) - if (capabLen != BgpConstants.Open.Capabilities.As4Octet.LENGTH) { - // ERROR: 4-octet AS Number Capability Length Error - String errorMsg = "4-octet AS Number Capability Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - long as4Number = message.readUnsignedInt(); - - bgpSession.remoteInfo().setAs4OctetCapability(); - bgpSession.remoteInfo().setAs4Number(as4Number); - - // - // Copy remote 4-octet AS Number Capabilities and AS - // Number. This is a temporary setting until local AS - // number configuration is supported. - // - bgpSession.localInfo().setAs4OctetCapability(); - bgpSession.localInfo().setAs4Number(as4Number); - log.debug("BGP RX OPEN Capability: AS4 Number = {}", - as4Number); - break; - - default: - // Unknown Capability: ignore it - log.debug("BGP RX OPEN Capability Code = {} Length = {}", - capabCode, capabLen); - message.readBytes(capabLen); - break; - } - - - } - break; - default: - // Unknown Parameter Type: ignore it - log.debug("BGP RX OPEN Parameter Type = {} Length = {}", - paramType, paramLen); - message.readBytes(paramLen); - break; - } - } - } - - /** - * Prepares the Capabilities for the BGP OPEN message. - * - * @param localInfo the BGP Session local information to use - * @return the buffer with the BGP Capabilities to transmit - */ - private static ChannelBuffer prepareBgpOpenCapabilities( - BgpSessionInfo localInfo) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // - // Write the Multiprotocol Extensions Capabilities - // - - // IPv4 unicast - if (localInfo.ipv4Unicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST); - } - // IPv4 multicast - if (localInfo.ipv4Multicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST); - } - // IPv6 unicast - if (localInfo.ipv6Unicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST); - } - // IPv6 multicast - if (localInfo.ipv6Multicast()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Param len - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE); // Capab. code - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH); // Capab. len - message.writeShort( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6); - message.writeByte(0); // Reserved field - message.writeByte( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST); - } - - // 4 octet AS path capability - if (localInfo.as4OctetCapability()) { - message.writeByte(BgpConstants.Open.Capabilities.TYPE); // Param type - message.writeByte(BgpConstants.Open.Capabilities.MIN_LENGTH + - BgpConstants.Open.Capabilities.As4Octet.LENGTH); // Param len - message.writeByte(BgpConstants.Open.Capabilities.As4Octet.CODE); // Capab. code - message.writeByte(BgpConstants.Open.Capabilities.As4Octet.LENGTH); // Capab. len - message.writeInt((int) localInfo.as4Number()); - } - return message; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java deleted file mode 100644 index 24d1a8da..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteEntry.java +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import com.google.common.base.MoreObjects; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onosproject.routing.RouteEntry; - -import java.util.ArrayList; -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Represents a route in BGP. - */ -public class BgpRouteEntry extends RouteEntry { - private final BgpSession bgpSession; // The BGP Session the route was - // received on - private final byte origin; // Route ORIGIN: IGP, EGP, INCOMPLETE - private final AsPath asPath; // The AS Path - private final long localPref; // The local preference for the route - private long multiExitDisc = BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC; - - /** - * Class constructor. - * - * @param bgpSession the BGP Session the route was received on - * @param prefix the prefix of the route - * @param nextHop the next hop of the route - * @param origin the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE - * @param asPath the AS path - * @param localPref the route local preference - */ - public BgpRouteEntry(BgpSession bgpSession, IpPrefix prefix, - IpAddress nextHop, byte origin, - BgpRouteEntry.AsPath asPath, long localPref) { - super(prefix, nextHop); - this.bgpSession = checkNotNull(bgpSession); - this.origin = origin; - this.asPath = checkNotNull(asPath); - this.localPref = localPref; - } - - /** - * Gets the BGP Session the route was received on. - * - * @return the BGP Session the route was received on - */ - public BgpSession getBgpSession() { - return bgpSession; - } - - /** - * Gets the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE. - * - * @return the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE - */ - public byte getOrigin() { - return origin; - } - - /** - * Gets the route AS path. - * - * @return the route AS path - */ - public BgpRouteEntry.AsPath getAsPath() { - return asPath; - } - - /** - * Gets the route local preference. - * - * @return the route local preference - */ - public long getLocalPref() { - return localPref; - } - - /** - * Gets the route MED (Multi-Exit Discriminator). - * - * @return the route MED (Multi-Exit Discriminator) - */ - public long getMultiExitDisc() { - return multiExitDisc; - } - - /** - * Sets the route MED (Multi-Exit Discriminator). - * - * @param multiExitDisc the route MED (Multi-Exit Discriminator) to set - */ - void setMultiExitDisc(long multiExitDisc) { - this.multiExitDisc = multiExitDisc; - } - - /** - * Tests whether the route is originated from the local AS. - * <p> - * The route is considered originated from the local AS if the AS Path - * is empty or if it begins with an AS_SET (after skipping - * AS_CONFED_SEQUENCE and AS_CONFED_SET). - * </p> - * - * @return true if the route is originated from the local AS, otherwise - * false - */ - boolean isLocalRoute() { - PathSegment firstPathSegment = null; - - // Find the first Path Segment by ignoring the AS_CONFED_* segments - for (PathSegment pathSegment : asPath.getPathSegments()) { - if ((pathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) || - (pathSegment.getType() == BgpConstants.Update.AsPath.AS_SEQUENCE)) { - firstPathSegment = pathSegment; - break; - } - } - if (firstPathSegment == null) { - return true; // Local route: no path segments - } - // If the first path segment is AS_SET, the route is considered local - if (firstPathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) { - return true; - } - - return false; // The route is not local - } - - /** - * Gets the BGP Neighbor AS number the route was received from. - * <p> - * If the router is originated from the local AS, the return value is - * zero (BGP_AS_0). - * </p> - * - * @return the BGP Neighbor AS number the route was received from. - */ - long getNeighborAs() { - PathSegment firstPathSegment = null; - - if (isLocalRoute()) { - return BgpConstants.BGP_AS_0; - } - - // Find the first Path Segment by ignoring the AS_CONFED_* segments - for (PathSegment pathSegment : asPath.getPathSegments()) { - if ((pathSegment.getType() == BgpConstants.Update.AsPath.AS_SET) || - (pathSegment.getType() == BgpConstants.Update.AsPath.AS_SEQUENCE)) { - firstPathSegment = pathSegment; - break; - } - } - if (firstPathSegment == null) { - // NOTE: Shouldn't happen - should be captured by isLocalRoute() - return BgpConstants.BGP_AS_0; - } - - if (firstPathSegment.getSegmentAsNumbers().isEmpty()) { - // NOTE: Shouldn't happen. Should check during the parsing. - return BgpConstants.BGP_AS_0; - } - return firstPathSegment.getSegmentAsNumbers().get(0); - } - - /** - * Tests whether the AS Path contains a loop. - * <p> - * The test is done by comparing whether the AS Path contains the - * local AS number. - * </p> - * - * @param localAsNumber the local AS number to compare against - * @return true if the AS Path contains a loop, otherwise false - */ - boolean hasAsPathLoop(long localAsNumber) { - for (PathSegment pathSegment : asPath.getPathSegments()) { - for (Long asNumber : pathSegment.getSegmentAsNumbers()) { - if (asNumber.equals(localAsNumber)) { - return true; - } - } - } - return false; - } - - /** - * Compares this BGP route against another BGP route by using the - * BGP Decision Process. - * <p> - * NOTE: The comparison needs to be performed only on routes that have - * same IP Prefix. - * </p> - * - * @param other the BGP route to compare against - * @return true if this BGP route is better than the other BGP route - * or same, otherwise false - */ - boolean isBetterThan(BgpRouteEntry other) { - if (this == other) { - return true; // Return true if same route - } - - // Compare the LOCAL_PREF values: larger is better - if (getLocalPref() != other.getLocalPref()) { - return (getLocalPref() > other.getLocalPref()); - } - - // Compare the AS number in the path: smaller is better - if (getAsPath().getAsPathLength() != - other.getAsPath().getAsPathLength()) { - return getAsPath().getAsPathLength() < - other.getAsPath().getAsPathLength(); - } - - // Compare the Origin number: lower is better - if (getOrigin() != other.getOrigin()) { - return (getOrigin() < other.getOrigin()); - } - - // Compare the MED if the neighbor AS is same: larger is better - medLabel: { - if (isLocalRoute() || other.isLocalRoute()) { - // Compare MEDs for non-local routes only - break medLabel; - } - long thisNeighborAs = getNeighborAs(); - if (thisNeighborAs != other.getNeighborAs()) { - break medLabel; // AS number is different - } - if (thisNeighborAs == BgpConstants.BGP_AS_0) { - break medLabel; // Invalid AS number - } - - // Compare the MED - if (getMultiExitDisc() != other.getMultiExitDisc()) { - return (getMultiExitDisc() > other.getMultiExitDisc()); - } - } - - // Compare the peer BGP ID: lower is better - Ip4Address peerBgpId = getBgpSession().remoteInfo().bgpId(); - Ip4Address otherPeerBgpId = other.getBgpSession().remoteInfo().bgpId(); - if (!peerBgpId.equals(otherPeerBgpId)) { - return (peerBgpId.compareTo(otherPeerBgpId) < 0); - } - - // Compare the peer BGP address: lower is better - Ip4Address peerAddress = getBgpSession().remoteInfo().ip4Address(); - Ip4Address otherPeerAddress = - other.getBgpSession().remoteInfo().ip4Address(); - if (!peerAddress.equals(otherPeerAddress)) { - return (peerAddress.compareTo(otherPeerAddress) < 0); - } - - return true; // Routes are same. Shouldn't happen? - } - - /** - * A class to represent AS Path Segment. - */ - public static class PathSegment { - // Segment type: AS_SET(1), AS_SEQUENCE(2), AS_CONFED_SEQUENCE(3), - // AS_CONFED_SET(4) - private final byte type; - private final ArrayList<Long> segmentAsNumbers; // Segment AS numbers - - /** - * Constructor. - * - * @param type the Path Segment Type: AS_SET(1), AS_SEQUENCE(2), - * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4) - * @param segmentAsNumbers the Segment AS numbers - */ - PathSegment(byte type, ArrayList<Long> segmentAsNumbers) { - this.type = type; - this.segmentAsNumbers = checkNotNull(segmentAsNumbers); - } - - /** - * Gets the Path Segment Type: AS_SET(1), AS_SEQUENCE(2), - * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4). - * - * @return the Path Segment Type: AS_SET(1), AS_SEQUENCE(2), - * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4) - */ - public byte getType() { - return type; - } - - /** - * Gets the Path Segment AS Numbers. - * - * @return the Path Segment AS Numbers - */ - public ArrayList<Long> getSegmentAsNumbers() { - return segmentAsNumbers; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - - if (!(other instanceof PathSegment)) { - return false; - } - - PathSegment otherPathSegment = (PathSegment) other; - return Objects.equals(this.type, otherPathSegment.type) && - Objects.equals(this.segmentAsNumbers, - otherPathSegment.segmentAsNumbers); - } - - @Override - public int hashCode() { - return Objects.hash(type, segmentAsNumbers); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("type", BgpConstants.Update.AsPath.typeToString(type)) - .add("segmentAsNumbers", this.segmentAsNumbers) - .toString(); - } - } - - /** - * A class to represent AS Path. - */ - public static class AsPath { - private final ArrayList<PathSegment> pathSegments; - private final int asPathLength; // Precomputed AS Path Length - - /** - * Constructor. - * - * @param pathSegments the Path Segments of the Path - */ - AsPath(ArrayList<PathSegment> pathSegments) { - this.pathSegments = checkNotNull(pathSegments); - - // - // Precompute the AS Path Length: - // - AS_SET counts as 1 - // - AS_SEQUENCE counts how many AS numbers are included - // - AS_CONFED_SEQUENCE and AS_CONFED_SET are ignored - // - int pl = 0; - for (PathSegment pathSegment : pathSegments) { - switch (pathSegment.getType()) { - case BgpConstants.Update.AsPath.AS_SET: - pl++; // AS_SET counts as 1 - break; - case BgpConstants.Update.AsPath.AS_SEQUENCE: - // Count each AS number - pl += pathSegment.getSegmentAsNumbers().size(); - break; - case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE: - break; // Ignore - case BgpConstants.Update.AsPath.AS_CONFED_SET: - break; // Ignore - default: - // NOTE: What to do if the Path Segment type is unknown? - break; - } - } - asPathLength = pl; - } - - /** - * Gets the AS Path Segments. - * - * @return the AS Path Segments - */ - public ArrayList<PathSegment> getPathSegments() { - return pathSegments; - } - - /** - * Gets the AS Path Length as considered by the BGP Decision Process. - * - * @return the AS Path Length as considered by the BGP Decision Process - */ - int getAsPathLength() { - return asPathLength; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - - if (!(other instanceof AsPath)) { - return false; - } - - AsPath otherAsPath = (AsPath) other; - return Objects.equals(this.pathSegments, otherAsPath.pathSegments); - } - - @Override - public int hashCode() { - return pathSegments.hashCode(); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("pathSegments", this.pathSegments) - .toString(); - } - } - - /** - * Compares whether two objects are equal. - * <p> - * NOTE: The bgpSession field is excluded from the comparison. - * </p> - * - * @return true if the two objects are equal, otherwise false. - */ - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - - // - // NOTE: Subclasses are considered as change of identity, hence - // equals() will return false if the class type doesn't match. - // - if (other == null || getClass() != other.getClass()) { - return false; - } - - if (!super.equals(other)) { - return false; - } - - // NOTE: The bgpSession field is excluded from the comparison - BgpRouteEntry otherRoute = (BgpRouteEntry) other; - return (this.origin == otherRoute.origin) && - Objects.equals(this.asPath, otherRoute.asPath) && - (this.localPref == otherRoute.localPref) && - (this.multiExitDisc == otherRoute.multiExitDisc); - } - - /** - * Computes the hash code. - * <p> - * NOTE: We return the base class hash code to avoid expensive computation - * </p> - * - * @return the object hash code - */ - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("prefix", prefix()) - .add("nextHop", nextHop()) - .add("bgpId", bgpSession.remoteInfo().bgpId()) - .add("origin", BgpConstants.Update.Origin.typeToString(origin)) - .add("asPath", asPath) - .add("localPref", localPref) - .add("multiExitDisc", multiExitDisc) - .toString(); - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java deleted file mode 100644 index ec020230..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpRouteSelector.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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.routing.bgp; - -import org.onlab.packet.IpPrefix; -import org.onosproject.routing.RouteUpdate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collection; -import java.util.LinkedList; - -/** - * Class to receive and process the BGP routes from each BGP Session/Peer. - */ -class BgpRouteSelector { - private static final Logger log = - LoggerFactory.getLogger(BgpRouteSelector.class); - - private BgpSessionManager bgpSessionManager; - - /** - * Constructor. - * - * @param bgpSessionManager the BGP Session Manager to use - */ - BgpRouteSelector(BgpSessionManager bgpSessionManager) { - this.bgpSessionManager = bgpSessionManager; - } - - /** - * Processes route entry updates: added/updated and deleted route - * entries. - * - * @param bgpSession the BGP session the route entry updates were - * received on - * @param addedBgpRouteEntries the added/updated route entries to process - * @param deletedBgpRouteEntries the deleted route entries to process - */ - synchronized void routeUpdates(BgpSession bgpSession, - Collection<BgpRouteEntry> addedBgpRouteEntries, - Collection<BgpRouteEntry> deletedBgpRouteEntries) { - Collection<RouteUpdate> routeUpdates = new LinkedList<>(); - RouteUpdate routeUpdate; - - if (bgpSessionManager.isShutdown()) { - return; // Ignore any leftover updates if shutdown - } - // Process the deleted route entries - for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) { - routeUpdate = processDeletedRoute(bgpSession, bgpRouteEntry); - if (routeUpdate != null) { - routeUpdates.add(routeUpdate); - } - } - - // Process the added/updated route entries - for (BgpRouteEntry bgpRouteEntry : addedBgpRouteEntries) { - routeUpdate = processAddedRoute(bgpSession, bgpRouteEntry); - if (routeUpdate != null) { - routeUpdates.add(routeUpdate); - } - } - bgpSessionManager.getRouteListener().update(routeUpdates); - } - - /** - * Processes an added/updated route entry. - * - * @param bgpSession the BGP session the route entry update was received on - * @param bgpRouteEntry the added/updated route entry - * @return the result route update that should be forwarded to the - * Route Listener, or null if no route update should be forwarded - */ - private RouteUpdate processAddedRoute(BgpSession bgpSession, - BgpRouteEntry bgpRouteEntry) { - RouteUpdate routeUpdate; - BgpRouteEntry bestBgpRouteEntry = - bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix()); - - // - // Install the new route entry if it is better than the - // current best route. - // - if ((bestBgpRouteEntry == null) || - bgpRouteEntry.isBetterThan(bestBgpRouteEntry)) { - bgpSessionManager.addBgpRoute(bgpRouteEntry); - routeUpdate = - new RouteUpdate(RouteUpdate.Type.UPDATE, bgpRouteEntry); - return routeUpdate; - } - - // - // If the route entry arrived on the same BGP Session as - // the current best route, then elect the next best route - // and install it. - // - if (bestBgpRouteEntry.getBgpSession() != - bgpRouteEntry.getBgpSession()) { - return null; // Nothing to do - } - - // Find the next best route - bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix()); - if (bestBgpRouteEntry == null) { - // - // TODO: Shouldn't happen. Install the new route as a - // pre-caution. - // - log.debug("BGP next best route for prefix {} is missing. " + - "Adding the route that is currently processed.", - bgpRouteEntry.prefix()); - bestBgpRouteEntry = bgpRouteEntry; - } - - // Install the next best route - bgpSessionManager.addBgpRoute(bestBgpRouteEntry); - routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, - bestBgpRouteEntry); - return routeUpdate; - } - - /** - * Processes a deleted route entry. - * - * @param bgpSession the BGP session the route entry update was received on - * @param bgpRouteEntry the deleted route entry - * @return the result route update that should be forwarded to the - * Route Listener, or null if no route update should be forwarded - */ - private RouteUpdate processDeletedRoute(BgpSession bgpSession, - BgpRouteEntry bgpRouteEntry) { - RouteUpdate routeUpdate; - BgpRouteEntry bestBgpRouteEntry = - bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix()); - - // - // Remove the route entry only if it was the best one. - // Install the the next best route if it exists. - // - // NOTE: We intentionally use "==" instead of method equals(), - // because we need to check whether this is same object. - // - if (bgpRouteEntry != bestBgpRouteEntry) { - return null; // Nothing to do - } - - // - // Find the next best route - // - bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix()); - if (bestBgpRouteEntry != null) { - // Install the next best route - bgpSessionManager.addBgpRoute(bestBgpRouteEntry); - routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, - bestBgpRouteEntry); - return routeUpdate; - } - - // - // No route found. Remove the route entry - // - bgpSessionManager.removeBgpRoute(bgpRouteEntry.prefix()); - routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, bgpRouteEntry); - return routeUpdate; - } - - /** - * Finds the best route entry among all BGP Sessions. - * - * @param prefix the prefix of the route - * @return the best route if found, otherwise null - */ - private BgpRouteEntry findBestBgpRoute(IpPrefix prefix) { - BgpRouteEntry bestRoute = null; - - // Iterate across all BGP Sessions and select the best route - for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) { - BgpRouteEntry route = bgpSession.findBgpRoute(prefix); - if (route == null) { - continue; - } - if ((bestRoute == null) || route.isBetterThan(bestRoute)) { - bestRoute = route; - } - } - return bestRoute; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java deleted file mode 100644 index dedf6ac3..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSession.java +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.SimpleChannelHandler; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.Timer; -import org.jboss.netty.util.TimerTask; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.Ip6Prefix; -import org.onlab.packet.IpPrefix; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.Collections; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; - -/** - * Class for handling the BGP peer sessions. - * There is one instance per each BGP peer session. - */ -public class BgpSession extends SimpleChannelHandler { - private static final Logger log = - LoggerFactory.getLogger(BgpSession.class); - - private final BgpSessionManager bgpSessionManager; - - // Local flag to indicate the session is closed. - // It is used to avoid the Netty's asynchronous closing of a channel. - private boolean isClosed = false; - - // BGP session info: local and remote - private final BgpSessionInfo localInfo; // BGP session local info - private final BgpSessionInfo remoteInfo; // BGP session remote info - - // Timers state - private Timer timer = new HashedWheelTimer(); - private volatile Timeout keepaliveTimeout; // Periodic KEEPALIVE - private volatile Timeout sessionTimeout; // Session timeout - - // BGP RIB-IN routing entries from this peer - private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn4 = - new ConcurrentHashMap<>(); - private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRibIn6 = - new ConcurrentHashMap<>(); - - /** - * Constructor for a given BGP Session Manager. - * - * @param bgpSessionManager the BGP Session Manager to use - */ - BgpSession(BgpSessionManager bgpSessionManager) { - this.bgpSessionManager = bgpSessionManager; - this.localInfo = new BgpSessionInfo(); - this.remoteInfo = new BgpSessionInfo(); - - // NOTE: We support only BGP4 - this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION); - } - - /** - * Gets the BGP Session Manager. - * - * @return the BGP Session Manager - */ - BgpSessionManager getBgpSessionManager() { - return bgpSessionManager; - } - - /** - * Gets the BGP Session local information. - * - * @return the BGP Session local information. - */ - public BgpSessionInfo localInfo() { - return localInfo; - } - - /** - * Gets the BGP Session remote information. - * - * @return the BGP Session remote information. - */ - public BgpSessionInfo remoteInfo() { - return remoteInfo; - } - - /** - * Gets the BGP Multiprotocol Extensions for the session. - * - * @return true if the BGP Multiprotocol Extensions are enabled for the - * session, otherwise false - */ - public boolean mpExtensions() { - return remoteInfo.mpExtensions() && localInfo.mpExtensions(); - } - - /** - * Gets the BGP session 4 octet AS path capability. - * - * @return true when the BGP session is 4 octet AS path capable - */ - public boolean isAs4OctetCapable() { - return remoteInfo.as4OctetCapability() && - localInfo.as4OctetCapability(); - } - - /** - * Gets the IPv4 BGP RIB-IN routing entries. - * - * @return the IPv4 BGP RIB-IN routing entries - */ - public Collection<BgpRouteEntry> getBgpRibIn4() { - return bgpRibIn4.values(); - } - - /** - * Gets the IPv6 BGP RIB-IN routing entries. - * - * @return the IPv6 BGP RIB-IN routing entries - */ - public Collection<BgpRouteEntry> getBgpRibIn6() { - return bgpRibIn6.values(); - } - - /** - * Finds an IPv4 BGP routing entry for a prefix in the IPv4 BGP RIB-IN. - * - * @param prefix the IPv4 prefix of the route to search for - * @return the IPv4 BGP routing entry if found, otherwise null - */ - public BgpRouteEntry findBgpRoute(Ip4Prefix prefix) { - return bgpRibIn4.get(prefix); - } - - /** - * Finds an IPv6 BGP routing entry for a prefix in the IPv6 BGP RIB-IN. - * - * @param prefix the IPv6 prefix of the route to search for - * @return the IPv6 BGP routing entry if found, otherwise null - */ - public BgpRouteEntry findBgpRoute(Ip6Prefix prefix) { - return bgpRibIn6.get(prefix); - } - - /** - * Finds a BGP routing entry for a prefix in the BGP RIB-IN. The prefix - * can be either IPv4 or IPv6. - * - * @param prefix the IP prefix of the route to search for - * @return the BGP routing entry if found, otherwise null - */ - public BgpRouteEntry findBgpRoute(IpPrefix prefix) { - if (prefix.isIp4()) { - // IPv4 prefix - Ip4Prefix ip4Prefix = prefix.getIp4Prefix(); - return bgpRibIn4.get(ip4Prefix); - } - - // IPv6 prefix - Ip6Prefix ip6Prefix = prefix.getIp6Prefix(); - return bgpRibIn6.get(ip6Prefix); - } - - /** - * Adds a BGP route. The route can be either IPv4 or IPv6. - * - * @param bgpRouteEntry the BGP route entry to use - */ - void addBgpRoute(BgpRouteEntry bgpRouteEntry) { - if (bgpRouteEntry.isIp4()) { - // IPv4 route - Ip4Prefix ip4Prefix = bgpRouteEntry.prefix().getIp4Prefix(); - bgpRibIn4.put(ip4Prefix, bgpRouteEntry); - } else { - // IPv6 route - Ip6Prefix ip6Prefix = bgpRouteEntry.prefix().getIp6Prefix(); - bgpRibIn6.put(ip6Prefix, bgpRouteEntry); - } - } - - /** - * Removes an IPv4 BGP route for a prefix. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeBgpRoute(Ip4Prefix prefix) { - return (bgpRibIn4.remove(prefix) != null); - } - - /** - * Removes an IPv6 BGP route for a prefix. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeBgpRoute(Ip6Prefix prefix) { - return (bgpRibIn6.remove(prefix) != null); - } - - /** - * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeBgpRoute(IpPrefix prefix) { - if (prefix.isIp4()) { - return (bgpRibIn4.remove(prefix.getIp4Prefix()) != null); // IPv4 - } - return (bgpRibIn6.remove(prefix.getIp6Prefix()) != null); // IPv6 - } - - /** - * Tests whether the session is closed. - * <p> - * NOTE: We use this method to avoid the Netty's asynchronous closing - * of a channel. - * </p> - * @return true if the session is closed - */ - boolean isClosed() { - return isClosed; - } - - /** - * Closes the session. - * - * @param ctx the Channel Handler Context - */ - void closeSession(ChannelHandlerContext ctx) { - timer.stop(); - closeChannel(ctx); - } - - /** - * Closes the Netty channel. - * - * @param ctx the Channel Handler Context - */ - void closeChannel(ChannelHandlerContext ctx) { - isClosed = true; - ctx.getChannel().close(); - } - - @Override - public void channelOpen(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - bgpSessionManager.addSessionChannel(channelEvent.getChannel()); - } - - @Override - public void channelClosed(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - bgpSessionManager.removeSessionChannel(channelEvent.getChannel()); - } - - @Override - public void channelConnected(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - localInfo.setAddress(ctx.getChannel().getLocalAddress()); - remoteInfo.setAddress(ctx.getChannel().getRemoteAddress()); - - // Assign the local and remote IPv4 addresses - InetAddress inetAddr; - if (localInfo.address() instanceof InetSocketAddress) { - inetAddr = ((InetSocketAddress) localInfo.address()).getAddress(); - localInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress())); - } - if (remoteInfo.address() instanceof InetSocketAddress) { - inetAddr = ((InetSocketAddress) remoteInfo.address()).getAddress(); - remoteInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress())); - } - - log.debug("BGP Session Connected from {} on {}", - remoteInfo.address(), localInfo.address()); - if (!bgpSessionManager.peerConnected(this)) { - log.debug("Cannot setup BGP Session Connection from {}. Closing...", - remoteInfo.address()); - ctx.getChannel().close(); - } - - // - // Assign the local BGP ID - // NOTE: This should be configuration-based - // - localInfo.setBgpId(bgpSessionManager.getMyBgpId()); - } - - @Override - public void channelDisconnected(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - log.debug("BGP Session Disconnected from {} on {}", - ctx.getChannel().getRemoteAddress(), - ctx.getChannel().getLocalAddress()); - processChannelDisconnected(); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { - log.debug("BGP Session Exception Caught from {} on {}: {}", - ctx.getChannel().getRemoteAddress(), - ctx.getChannel().getLocalAddress(), - e); - processChannelDisconnected(); - } - - /** - * Processes the channel being disconnected. - */ - private void processChannelDisconnected() { - // - // Withdraw the routes advertised by this BGP peer - // - // NOTE: We must initialize the RIB-IN before propagating the withdraws - // for further processing. Otherwise, the BGP Decision Process - // will use those routes again. - // - Collection<BgpRouteEntry> deletedRoutes4 = bgpRibIn4.values(); - Collection<BgpRouteEntry> deletedRoutes6 = bgpRibIn6.values(); - bgpRibIn4 = new ConcurrentHashMap<>(); - bgpRibIn6 = new ConcurrentHashMap<>(); - - // Push the updates to the BGP Merged RIB - BgpRouteSelector bgpRouteSelector = - bgpSessionManager.getBgpRouteSelector(); - Collection<BgpRouteEntry> addedRoutes = Collections.emptyList(); - bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4); - bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes6); - - bgpSessionManager.peerDisconnected(this); - } - - /** - * Restarts the BGP KeepaliveTimer. - * - * @param ctx the Channel Handler Context to use - */ - void restartKeepaliveTimer(ChannelHandlerContext ctx) { - long localKeepaliveInterval = 0; - - // - // Compute the local Keepalive interval - // - if (localInfo.holdtime() != 0) { - localKeepaliveInterval = Math.max(localInfo.holdtime() / - BgpConstants.BGP_KEEPALIVE_PER_HOLD_INTERVAL, - BgpConstants.BGP_KEEPALIVE_MIN_INTERVAL); - } - - // Restart the Keepalive timer - if (localKeepaliveInterval == 0) { - return; // Nothing to do - } - keepaliveTimeout = timer.newTimeout(new TransmitKeepaliveTask(ctx), - localKeepaliveInterval, - TimeUnit.SECONDS); - } - - /** - * Task class for transmitting KEEPALIVE messages. - */ - private final class TransmitKeepaliveTask implements TimerTask { - private final ChannelHandlerContext ctx; - - /** - * Constructor for given Channel Handler Context. - * - * @param ctx the Channel Handler Context to use - */ - TransmitKeepaliveTask(ChannelHandlerContext ctx) { - this.ctx = ctx; - } - - @Override - public void run(Timeout timeout) throws Exception { - if (timeout.isCancelled()) { - return; - } - if (!ctx.getChannel().isOpen()) { - return; - } - - // Transmit the KEEPALIVE - ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive(); - ctx.getChannel().write(txMessage); - - // Restart the KEEPALIVE timer - restartKeepaliveTimer(ctx); - } - } - - /** - * Restarts the BGP Session Timeout Timer. - * - * @param ctx the Channel Handler Context to use - */ - void restartSessionTimeoutTimer(ChannelHandlerContext ctx) { - if (remoteInfo.holdtime() == 0) { - return; // Nothing to do - } - if (sessionTimeout != null) { - sessionTimeout.cancel(); - } - sessionTimeout = timer.newTimeout(new SessionTimeoutTask(ctx), - remoteInfo.holdtime(), - TimeUnit.SECONDS); - } - - /** - * Task class for BGP Session timeout. - */ - private final class SessionTimeoutTask implements TimerTask { - private final ChannelHandlerContext ctx; - - /** - * Constructor for given Channel Handler Context. - * - * @param ctx the Channel Handler Context to use - */ - SessionTimeoutTask(ChannelHandlerContext ctx) { - this.ctx = ctx; - } - - @Override - public void run(Timeout timeout) throws Exception { - if (timeout.isCancelled()) { - return; - } - if (!ctx.getChannel().isOpen()) { - return; - } - - log.debug("BGP Session Timeout: peer {}", remoteInfo.address()); - // - // ERROR: Invalid Optional Parameter Length field: Unspecific - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.HoldTimerExpired.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - closeChannel(ctx); - } - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java deleted file mode 100644 index a1274556..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionInfo.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * 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.routing.bgp; - -import org.onlab.packet.Ip4Address; - -import java.net.SocketAddress; - -/** - * Class for keeping information about a BGP session. - * - * There are two instances per each BGP peer session: one to keep the local - * information about the BGP session, and another to keep information about - * the remote BGP peer. - */ -public class BgpSessionInfo { - private SocketAddress address; // IP addr/port - private Ip4Address ip4Address; // IPv4 address - private int bgpVersion; // 1 octet - private long asNumber; // AS number: 2 octets - private long as4Number; // AS4 number: 4 octets - private long holdtime; // 2 octets - private Ip4Address bgpId; // 4 octets -> IPv4 address - private boolean mpExtensions; // Multiprotocol Extensions - // enabled: RFC 4760 - private boolean ipv4Unicast; // IPv4/UNICAST AFI/SAFI - private boolean ipv4Multicast; // IPv4/MULTICAST AFI/SAFI - private boolean ipv6Unicast; // IPv6/UNICAST AFI/SAFI - private boolean ipv6Multicast; // IPv6/MULTICAST AFI/SAFI - private boolean as4OctetCapability; // AS 4 octet path capability - - /** - * Gets the BGP session address: local or remote. - * - * @return the BGP session address - */ - public SocketAddress address() { - return this.address; - } - - /** - * Sets the BGP session address: local or remote. - * - * @param address the BGP session address to set - */ - public void setAddress(SocketAddress address) { - this.address = address; - } - - /** - * Gets the BGP session IPv4 address: local or remote. - * - * @return the BGP session IPv4 address - */ - public Ip4Address ip4Address() { - return this.ip4Address; - } - - /** - * Sets the BGP session IPv4 address: local or remote. - * - * @param ip4Address the BGP session IPv4 address to set - */ - public void setIp4Address(Ip4Address ip4Address) { - this.ip4Address = ip4Address; - } - - /** - * Gets the BGP session BGP version: local or remote. - * - * @return the BGP session BGP version - */ - public int bgpVersion() { - return this.bgpVersion; - } - - /** - * Sets the BGP session BGP version: local or remote. - * - * @param bgpVersion the BGP session BGP version to set - */ - public void setBgpVersion(int bgpVersion) { - this.bgpVersion = bgpVersion; - } - - /** - * Gets the BGP session AS number: local or remote. - * - * @return the BGP session AS number - */ - public long asNumber() { - return this.asNumber; - } - - /** - * Sets the BGP session AS number: local or remote. - * - * @param asNumber the BGP session AS number to set - */ - public void setAsNumber(long asNumber) { - this.asNumber = asNumber; - } - - /** - * Gets the BGP session AS4 number: local or remote. - * - * @return the BGP session AS4 number - */ - public long as4Number() { - return this.as4Number; - } - - /** - * Sets the BGP session AS4 number: local or remote. - * - * @param as4Number the BGP session AS4 number to set - */ - public void setAs4Number(long as4Number) { - this.as4Number = as4Number; - } - - /** - * Gets the BGP session holdtime: local or remote. - * - * @return the BGP session holdtime - */ - public long holdtime() { - return this.holdtime; - } - - /** - * Sets the BGP session holdtime: local or remote. - * - * @param holdtime the BGP session holdtime to set - */ - public void setHoldtime(long holdtime) { - this.holdtime = holdtime; - } - - /** - * Gets the BGP session BGP Identifier as an IPv4 address: local or remote. - * - * @return the BGP session BGP Identifier as an IPv4 address - */ - public Ip4Address bgpId() { - return this.bgpId; - } - - /** - * Sets the BGP session BGP Identifier as an IPv4 address: local or remote. - * - * @param bgpId the BGP session BGP Identifier to set - */ - public void setBgpId(Ip4Address bgpId) { - this.bgpId = bgpId; - } - - /** - * Gets the BGP Multiprotocol Extensions: local or remote. - * - * @return true if the BGP Multiprotocol Extensions are enabled, otherwise - * false - */ - public boolean mpExtensions() { - return this.mpExtensions; - } - - /** - * Gets the BGP session AFI/SAFI configuration for IPv4 unicast: local or - * remote. - * - * @return the BGP session AFI/SAFI configuration for IPv4 unicast - */ - public boolean ipv4Unicast() { - return ipv4Unicast; - } - - /** - * Sets the BGP session AFI/SAFI configuration for IPv4 unicast: local or - * remote. - */ - public void setIpv4Unicast() { - this.mpExtensions = true; - this.ipv4Unicast = true; - } - - /** - * Gets the BGP session AFI/SAFI configuration for IPv4 multicast: local or - * remote. - * - * @return the BGP session AFI/SAFI configuration for IPv4 multicast - */ - public boolean ipv4Multicast() { - return ipv4Multicast; - } - - /** - * Sets the BGP session AFI/SAFI configuration for IPv4 multicast: local or - * remote. - */ - public void setIpv4Multicast() { - this.mpExtensions = true; - this.ipv4Multicast = true; - } - - /** - * Gets the BGP session AFI/SAFI configuration for IPv6 unicast: local or - * remote. - * - * @return the BGP session AFI/SAFI configuration for IPv6 unicast - */ - public boolean ipv6Unicast() { - return ipv6Unicast; - } - - /** - * Sets the BGP session AFI/SAFI configuration for IPv6 unicast: local or - * remote. - */ - void setIpv6Unicast() { - this.mpExtensions = true; - this.ipv6Unicast = true; - } - - /** - * Gets the BGP session AFI/SAFI configuration for IPv6 multicast: local or - * remote. - * - * @return the BGP session AFI/SAFI configuration for IPv6 multicast - */ - public boolean ipv6Multicast() { - return ipv6Multicast; - } - - /** - * Sets the BGP session AFI/SAFI configuration for IPv6 multicast: local or - * remote. - */ - public void setIpv6Multicast() { - this.mpExtensions = true; - this.ipv6Multicast = true; - } - - /** - * Gets the BGP session 4 octet AS path capability: local or remote. - * - * @return true when the BGP session has 4 octet AS path capability - */ - public boolean as4OctetCapability() { - return this.as4OctetCapability; - } - - /** - * Sets the BGP session 4 octet AS path capability. - */ - public void setAs4OctetCapability() { - this.as4OctetCapability = true; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java deleted file mode 100644 index ab8a0493..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpSessionManager.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -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.Modified; -import org.apache.felix.scr.annotations.Service; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelException; -import org.jboss.netty.channel.ChannelFactory; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.channel.group.ChannelGroup; -import org.jboss.netty.channel.group.DefaultChannelGroup; -import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.Ip6Prefix; -import org.onlab.packet.IpPrefix; -import org.onosproject.routing.BgpService; -import org.onosproject.routing.RouteListener; -import org.osgi.service.component.ComponentContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Collection; -import java.util.Dictionary; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.concurrent.Executors.newCachedThreadPool; -import static org.onlab.util.Tools.groupedThreads; - -/** - * BGP Session Manager class. - */ -@Component(immediate = true) -@Service -public class BgpSessionManager implements BgpInfoService, BgpService { - private static final Logger log = - LoggerFactory.getLogger(BgpSessionManager.class); - - boolean isShutdown = true; - private Channel serverChannel; // Listener for incoming BGP connections - private ServerBootstrap serverBootstrap; - private ChannelGroup allChannels = new DefaultChannelGroup(); - private ConcurrentMap<SocketAddress, BgpSession> bgpSessions = - new ConcurrentHashMap<>(); - private Ip4Address myBgpId; // Same BGP ID for all peers - - private BgpRouteSelector bgpRouteSelector = new BgpRouteSelector(this); - private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRoutes4 = - new ConcurrentHashMap<>(); - private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRoutes6 = - new ConcurrentHashMap<>(); - - private RouteListener routeListener; - - private static final int DEFAULT_BGP_PORT = 2000; - private int bgpPort; - - @Activate - protected void activate(ComponentContext context) { - readComponentConfiguration(context); - log.info("BgpSessionManager started"); - } - - @Deactivate - protected void deactivate() { - log.info("BgpSessionManager stopped"); - } - - /** - * Extracts properties from the component configuration context. - * - * @param context the component context - */ - private void readComponentConfiguration(ComponentContext context) { - Dictionary<?, ?> properties = context.getProperties(); - try { - String strPort = (String) properties.get("bgpPort"); - if (strPort != null) { - bgpPort = Integer.parseInt(strPort); - } else { - bgpPort = DEFAULT_BGP_PORT; - } - } catch (NumberFormatException | ClassCastException e) { - bgpPort = DEFAULT_BGP_PORT; - } - log.debug("BGP port is set to {}", bgpPort); - } - - @Modified - public void modified(ComponentContext context) { - // Blank @Modified method to catch modifications to the context. - // If no @Modified method exists, it seems @Activate is called again - // when the context is modified. - } - - /** - * Checks whether the BGP Session Manager is shutdown. - * - * @return true if the BGP Session Manager is shutdown, otherwise false - */ - boolean isShutdown() { - return this.isShutdown; - } - - /** - * Gets the route listener. - * - * @return the route listener to use - */ - RouteListener getRouteListener() { - return routeListener; - } - - /** - * Gets the BGP sessions. - * - * @return the BGP sessions - */ - public Collection<BgpSession> getBgpSessions() { - return bgpSessions.values(); - } - - /** - * Gets the selected IPv4 BGP routes among all BGP sessions. - * - * @return the selected IPv4 BGP routes among all BGP sessions - */ - public Collection<BgpRouteEntry> getBgpRoutes4() { - return bgpRoutes4.values(); - } - - /** - * Gets the selected IPv6 BGP routes among all BGP sessions. - * - * @return the selected IPv6 BGP routes among all BGP sessions - */ - public Collection<BgpRouteEntry> getBgpRoutes6() { - return bgpRoutes6.values(); - } - - /** - * Finds a BGP route for a prefix. The prefix can be either IPv4 or IPv6. - * - * @param prefix the prefix to use - * @return the BGP route if found, otherwise null - */ - BgpRouteEntry findBgpRoute(IpPrefix prefix) { - if (prefix.isIp4()) { - return bgpRoutes4.get(prefix.getIp4Prefix()); // IPv4 - } - return bgpRoutes6.get(prefix.getIp6Prefix()); // IPv6 - } - - /** - * Adds a BGP route. The route can be either IPv4 or IPv6. - * - * @param bgpRouteEntry the BGP route entry to use - */ - void addBgpRoute(BgpRouteEntry bgpRouteEntry) { - if (bgpRouteEntry.isIp4()) { - bgpRoutes4.put(bgpRouteEntry.prefix().getIp4Prefix(), // IPv4 - bgpRouteEntry); - } else { - bgpRoutes6.put(bgpRouteEntry.prefix().getIp6Prefix(), // IPv6 - bgpRouteEntry); - } - } - - /** - * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeBgpRoute(IpPrefix prefix) { - if (prefix.isIp4()) { - return (bgpRoutes4.remove(prefix.getIp4Prefix()) != null); // IPv4 - } - return (bgpRoutes6.remove(prefix.getIp6Prefix()) != null); // IPv6 - } - - /** - * Adds the channel for a BGP session. - * - * @param channel the channel to add - */ - void addSessionChannel(Channel channel) { - allChannels.add(channel); - } - - /** - * Removes the channel for a BGP session. - * - * @param channel the channel to remove - */ - void removeSessionChannel(Channel channel) { - allChannels.remove(channel); - } - - /** - * Processes the connection from a BGP peer. - * - * @param bgpSession the BGP session for the peer - * @return true if the connection can be established, otherwise false - */ - boolean peerConnected(BgpSession bgpSession) { - - // Test whether there is already a session from the same remote - if (bgpSessions.get(bgpSession.remoteInfo().address()) != null) { - return false; // Duplicate BGP session - } - bgpSessions.put(bgpSession.remoteInfo().address(), bgpSession); - - // - // If the first connection, set my BGP ID to the local address - // of the socket. - // - if (bgpSession.localInfo().address() instanceof InetSocketAddress) { - InetAddress inetAddr = - ((InetSocketAddress) bgpSession.localInfo().address()).getAddress(); - Ip4Address ip4Address = Ip4Address.valueOf(inetAddr.getAddress()); - updateMyBgpId(ip4Address); - } - return true; - } - - /** - * Processes the disconnection from a BGP peer. - * - * @param bgpSession the BGP session for the peer - */ - void peerDisconnected(BgpSession bgpSession) { - bgpSessions.remove(bgpSession.remoteInfo().address()); - } - - /** - * Conditionally updates the local BGP ID if it wasn't set already. - * <p/> - * NOTE: A BGP instance should use same BGP ID across all BGP sessions. - * - * @param ip4Address the IPv4 address to use as BGP ID - */ - private synchronized void updateMyBgpId(Ip4Address ip4Address) { - if (myBgpId == null) { - myBgpId = ip4Address; - log.debug("BGP: My BGP ID is {}", myBgpId); - } - } - - /** - * Gets the local BGP Identifier as an IPv4 address. - * - * @return the local BGP Identifier as an IPv4 address - */ - Ip4Address getMyBgpId() { - return myBgpId; - } - - /** - * Gets the BGP Route Selector. - * - * @return the BGP Route Selector - */ - BgpRouteSelector getBgpRouteSelector() { - return bgpRouteSelector; - } - - @Override - public void start(RouteListener routeListener) { - log.debug("BGP Session Manager start."); - isShutdown = false; - - this.routeListener = checkNotNull(routeListener); - - ChannelFactory channelFactory = new NioServerSocketChannelFactory( - newCachedThreadPool(groupedThreads("onos/bgp", "sm-boss-%d")), - newCachedThreadPool(groupedThreads("onos/bgp", "sm-worker-%d"))); - ChannelPipelineFactory pipelineFactory = () -> { - // Allocate a new session per connection - BgpSession bgpSessionHandler = - new BgpSession(BgpSessionManager.this); - BgpFrameDecoder bgpFrameDecoder = - new BgpFrameDecoder(bgpSessionHandler); - - // Setup the processing pipeline - ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("BgpFrameDecoder", bgpFrameDecoder); - pipeline.addLast("BgpSession", bgpSessionHandler); - return pipeline; - }; - InetSocketAddress listenAddress = - new InetSocketAddress(bgpPort); - - serverBootstrap = new ServerBootstrap(channelFactory); - // serverBootstrap.setOptions("reuseAddr", true); - serverBootstrap.setOption("child.keepAlive", true); - serverBootstrap.setOption("child.tcpNoDelay", true); - serverBootstrap.setPipelineFactory(pipelineFactory); - try { - serverChannel = serverBootstrap.bind(listenAddress); - allChannels.add(serverChannel); - } catch (ChannelException e) { - log.debug("Exception binding to BGP port {}: ", - listenAddress.getPort(), e); - } - } - - @Override - public void stop() { - isShutdown = true; - allChannels.close().awaitUninterruptibly(); - serverBootstrap.releaseExternalResources(); - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java deleted file mode 100644 index babc8507..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/BgpUpdate.java +++ /dev/null @@ -1,1707 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.apache.commons.lang3.tuple.Pair; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.Ip6Address; -import org.onlab.packet.Ip6Prefix; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * A class for handling BGP UPDATE messages. - */ -final class BgpUpdate { - private static final Logger log = LoggerFactory.getLogger(BgpUpdate.class); - - /** - * Default constructor. - * <p> - * The constructor is private to prevent creating an instance of - * this utility class. - */ - private BgpUpdate() { - } - - /** - * Processes BGP UPDATE message. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to process - */ - static void processBgpUpdate(BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message) { - DecodedBgpRoutes decodedBgpRoutes = new DecodedBgpRoutes(); - - int minLength = - BgpConstants.BGP_UPDATE_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH; - if (message.readableBytes() < minLength) { - log.debug("BGP RX UPDATE Error from {}: " + - "Message length {} too short. Must be at least {}", - bgpSession.remoteInfo().address(), - message.readableBytes(), minLength); - // - // ERROR: Bad Message Length - // - // Send NOTIFICATION and close the connection - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotificationBadMessageLength( - message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - return; - } - - log.debug("BGP RX UPDATE message from {}", - bgpSession.remoteInfo().address()); - - // - // Parse the UPDATE message - // - - // - // Parse the Withdrawn Routes - // - int withdrawnRoutesLength = message.readUnsignedShort(); - if (withdrawnRoutesLength > message.readableBytes()) { - // ERROR: Malformed Attribute List - actionsBgpUpdateMalformedAttributeList(bgpSession, ctx); - return; - } - Collection<Ip4Prefix> withdrawnPrefixes = null; - try { - withdrawnPrefixes = parsePackedIp4Prefixes(withdrawnRoutesLength, - message); - } catch (BgpMessage.BgpParseException e) { - // ERROR: Invalid Network Field - log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ", - bgpSession.remoteInfo().bgpId(), e); - actionsBgpUpdateInvalidNetworkField(bgpSession, ctx); - return; - } - for (Ip4Prefix prefix : withdrawnPrefixes) { - log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}", - bgpSession.remoteInfo().address(), prefix); - BgpRouteEntry bgpRouteEntry = bgpSession.findBgpRoute(prefix); - if (bgpRouteEntry != null) { - decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, - bgpRouteEntry); - } - } - - // - // Parse the Path Attributes - // - try { - parsePathAttributes(bgpSession, ctx, message, decodedBgpRoutes); - } catch (BgpMessage.BgpParseException e) { - log.debug("Exception parsing Path Attributes from BGP peer {}: ", - bgpSession.remoteInfo().bgpId(), e); - // NOTE: The session was already closed, so nothing else to do - return; - } - - // - // Update the BGP RIB-IN - // - for (Ip4Prefix ip4Prefix : - decodedBgpRoutes.deletedUnicastRoutes4.keySet()) { - bgpSession.removeBgpRoute(ip4Prefix); - } - // - for (BgpRouteEntry bgpRouteEntry : - decodedBgpRoutes.addedUnicastRoutes4.values()) { - bgpSession.addBgpRoute(bgpRouteEntry); - } - // - for (Ip6Prefix ip6Prefix : - decodedBgpRoutes.deletedUnicastRoutes6.keySet()) { - bgpSession.removeBgpRoute(ip6Prefix); - } - // - for (BgpRouteEntry bgpRouteEntry : - decodedBgpRoutes.addedUnicastRoutes6.values()) { - bgpSession.addBgpRoute(bgpRouteEntry); - } - - // - // Push the updates to the BGP Merged RIB - // - BgpRouteSelector bgpRouteSelector = - bgpSession.getBgpSessionManager().getBgpRouteSelector(); - bgpRouteSelector.routeUpdates(bgpSession, - decodedBgpRoutes.addedUnicastRoutes4.values(), - decodedBgpRoutes.deletedUnicastRoutes4.values()); - bgpRouteSelector.routeUpdates(bgpSession, - decodedBgpRoutes.addedUnicastRoutes6.values(), - decodedBgpRoutes.deletedUnicastRoutes6.values()); - - // Start the Session Timeout timer - bgpSession.restartSessionTimeoutTimer(ctx); - } - - /** - * Parse BGP Path Attributes from the BGP UPDATE message. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param message the message to parse - * @param decodedBgpRoutes the container to store the decoded BGP Route - * Entries. It might already contain some route entries such as withdrawn - * IPv4 prefixes - * @throws BgpMessage.BgpParseException - */ - // CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES - private static void parsePathAttributes( - BgpSession bgpSession, - ChannelHandlerContext ctx, - ChannelBuffer message, - DecodedBgpRoutes decodedBgpRoutes) - throws BgpMessage.BgpParseException { - - // - // Parsed values - // - Short origin = -1; // Mandatory - BgpRouteEntry.AsPath asPath = null; // Mandatory - // Legacy NLRI (RFC 4271). Mandatory NEXT_HOP if legacy NLRI is used - MpNlri legacyNlri = new MpNlri( - BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4, - BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST); - long multiExitDisc = // Optional - BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC; - Long localPref = null; // Mandatory - Long aggregatorAsNumber = null; // Optional: unused - Ip4Address aggregatorIpAddress = null; // Optional: unused - Collection<MpNlri> mpNlriReachList = new ArrayList<>(); // Optional - Collection<MpNlri> mpNlriUnreachList = new ArrayList<>(); // Optional - - // - // Get and verify the Path Attributes Length - // - int pathAttributeLength = message.readUnsignedShort(); - if (pathAttributeLength > message.readableBytes()) { - // ERROR: Malformed Attribute List - actionsBgpUpdateMalformedAttributeList(bgpSession, ctx); - String errorMsg = "Malformed Attribute List"; - throw new BgpMessage.BgpParseException(errorMsg); - } - if (pathAttributeLength == 0) { - return; - } - - // - // Parse the Path Attributes - // - int pathAttributeEnd = message.readerIndex() + pathAttributeLength; - while (message.readerIndex() < pathAttributeEnd) { - int attrFlags = message.readUnsignedByte(); - if (message.readerIndex() >= pathAttributeEnd) { - // ERROR: Malformed Attribute List - actionsBgpUpdateMalformedAttributeList(bgpSession, ctx); - String errorMsg = "Malformed Attribute List"; - throw new BgpMessage.BgpParseException(errorMsg); - } - int attrTypeCode = message.readUnsignedByte(); - - // The Attribute Flags - boolean optionalBit = ((0x80 & attrFlags) != 0); - boolean transitiveBit = ((0x40 & attrFlags) != 0); - boolean partialBit = ((0x20 & attrFlags) != 0); - boolean extendedLengthBit = ((0x10 & attrFlags) != 0); - - // The Attribute Length - int attrLen = 0; - int attrLenOctets = 1; - if (extendedLengthBit) { - attrLenOctets = 2; - } - if (message.readerIndex() + attrLenOctets > pathAttributeEnd) { - // ERROR: Malformed Attribute List - actionsBgpUpdateMalformedAttributeList(bgpSession, ctx); - String errorMsg = "Malformed Attribute List"; - throw new BgpMessage.BgpParseException(errorMsg); - } - if (extendedLengthBit) { - attrLen = message.readUnsignedShort(); - } else { - attrLen = message.readUnsignedByte(); - } - if (message.readerIndex() + attrLen > pathAttributeEnd) { - // ERROR: Malformed Attribute List - actionsBgpUpdateMalformedAttributeList(bgpSession, ctx); - String errorMsg = "Malformed Attribute List"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // Verify the Attribute Flags - verifyBgpUpdateAttributeFlags(bgpSession, ctx, attrTypeCode, - attrLen, attrFlags, message); - - // - // Extract the Attribute Value based on the Attribute Type Code - // - switch (attrTypeCode) { - - case BgpConstants.Update.Origin.TYPE: - // Attribute Type Code ORIGIN - origin = parseAttributeTypeOrigin(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - break; - - case BgpConstants.Update.AsPath.TYPE: - // Attribute Type Code AS_PATH - asPath = parseAttributeTypeAsPath(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - break; - - case BgpConstants.Update.NextHop.TYPE: - // Attribute Type Code NEXT_HOP - legacyNlri.nextHop4 = - parseAttributeTypeNextHop(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - break; - - case BgpConstants.Update.MultiExitDisc.TYPE: - // Attribute Type Code MULTI_EXIT_DISC - multiExitDisc = - parseAttributeTypeMultiExitDisc(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - break; - - case BgpConstants.Update.LocalPref.TYPE: - // Attribute Type Code LOCAL_PREF - localPref = - parseAttributeTypeLocalPref(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - break; - - case BgpConstants.Update.AtomicAggregate.TYPE: - // Attribute Type Code ATOMIC_AGGREGATE - parseAttributeTypeAtomicAggregate(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - // Nothing to do: this attribute is primarily informational - break; - - case BgpConstants.Update.Aggregator.TYPE: - // Attribute Type Code AGGREGATOR - Pair<Long, Ip4Address> aggregator = - parseAttributeTypeAggregator(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - aggregatorAsNumber = aggregator.getLeft(); - aggregatorIpAddress = aggregator.getRight(); - break; - - case BgpConstants.Update.MpReachNlri.TYPE: - // Attribute Type Code MP_REACH_NLRI - MpNlri mpNlriReach = - parseAttributeTypeMpReachNlri(bgpSession, ctx, - attrTypeCode, - attrLen, - attrFlags, message); - if (mpNlriReach != null) { - mpNlriReachList.add(mpNlriReach); - } - break; - - case BgpConstants.Update.MpUnreachNlri.TYPE: - // Attribute Type Code MP_UNREACH_NLRI - MpNlri mpNlriUnreach = - parseAttributeTypeMpUnreachNlri(bgpSession, ctx, - attrTypeCode, attrLen, - attrFlags, message); - if (mpNlriUnreach != null) { - mpNlriUnreachList.add(mpNlriUnreach); - } - break; - - default: - // NOTE: Parse any new Attribute Types if needed - if (!optionalBit) { - // ERROR: Unrecognized Well-known Attribute - actionsBgpUpdateUnrecognizedWellKnownAttribute( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, - message); - String errorMsg = "Unrecognized Well-known Attribute: " + - attrTypeCode; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // Skip the data from the unrecognized attribute - log.debug("BGP RX UPDATE message from {}: " + - "Unrecognized Attribute Type {}", - bgpSession.remoteInfo().address(), attrTypeCode); - message.skipBytes(attrLen); - break; - } - } - - // - // Parse the NLRI (Network Layer Reachability Information) - // - int nlriLength = message.readableBytes(); - try { - Collection<Ip4Prefix> addedPrefixes4 = - parsePackedIp4Prefixes(nlriLength, message); - // Store it inside the legacy NLRI wrapper - legacyNlri.nlri4 = addedPrefixes4; - } catch (BgpMessage.BgpParseException e) { - // ERROR: Invalid Network Field - log.debug("Exception parsing NLRI from BGP peer {}: ", - bgpSession.remoteInfo().bgpId(), e); - actionsBgpUpdateInvalidNetworkField(bgpSession, ctx); - // Rethrow the exception - throw e; - } - - // Verify the Well-known Attributes - verifyBgpUpdateWellKnownAttributes(bgpSession, ctx, origin, asPath, - localPref, legacyNlri, - mpNlriReachList); - - // - // Generate the deleted routes - // - for (MpNlri mpNlri : mpNlriUnreachList) { - BgpRouteEntry bgpRouteEntry; - - // The deleted IPv4 routes - for (Ip4Prefix prefix : mpNlri.nlri4) { - bgpRouteEntry = bgpSession.findBgpRoute(prefix); - if (bgpRouteEntry != null) { - decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, - bgpRouteEntry); - } - } - - // The deleted IPv6 routes - for (Ip6Prefix prefix : mpNlri.nlri6) { - bgpRouteEntry = bgpSession.findBgpRoute(prefix); - if (bgpRouteEntry != null) { - decodedBgpRoutes.deletedUnicastRoutes6.put(prefix, - bgpRouteEntry); - } - } - } - - // - // Generate the added routes - // - mpNlriReachList.add(legacyNlri); - for (MpNlri mpNlri : mpNlriReachList) { - BgpRouteEntry bgpRouteEntry; - - // The added IPv4 routes - for (Ip4Prefix prefix : mpNlri.nlri4) { - bgpRouteEntry = - new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop4, - origin.byteValue(), asPath, localPref); - bgpRouteEntry.setMultiExitDisc(multiExitDisc); - if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) { - log.debug("BGP RX UPDATE message IGNORED from {}: {} " + - "nextHop {}: contains AS Path loop", - bgpSession.remoteInfo().address(), prefix, - mpNlri.nextHop4); - continue; - } else { - log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}", - bgpSession.remoteInfo().address(), prefix, - mpNlri.nextHop4); - } - // Remove from the collection of deleted routes - decodedBgpRoutes.deletedUnicastRoutes4.remove(prefix); - decodedBgpRoutes.addedUnicastRoutes4.put(prefix, - bgpRouteEntry); - } - - // The added IPv6 routes - for (Ip6Prefix prefix : mpNlri.nlri6) { - bgpRouteEntry = - new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop6, - origin.byteValue(), asPath, localPref); - bgpRouteEntry.setMultiExitDisc(multiExitDisc); - if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) { - log.debug("BGP RX UPDATE message IGNORED from {}: {} " + - "nextHop {}: contains AS Path loop", - bgpSession.remoteInfo().address(), prefix, - mpNlri.nextHop6); - continue; - } else { - log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}", - bgpSession.remoteInfo().address(), prefix, - mpNlri.nextHop6); - } - // Remove from the collection of deleted routes - decodedBgpRoutes.deletedUnicastRoutes6.remove(prefix); - decodedBgpRoutes.addedUnicastRoutes6.put(prefix, - bgpRouteEntry); - } - } - } - - /** - * Verifies BGP UPDATE Well-known Attributes. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param origin the ORIGIN well-known mandatory attribute - * @param asPath the AS_PATH well-known mandatory attribute - * @param localPref the LOCAL_PREF required attribute - * @param legacyNlri the legacy NLRI. Encapsulates the NEXT_HOP well-known - * mandatory attribute (mandatory if legacy NLRI is used). - * @param mpNlriReachList the Multiprotocol NLRI attributes - * @throws BgpMessage.BgpParseException - */ - private static void verifyBgpUpdateWellKnownAttributes( - BgpSession bgpSession, - ChannelHandlerContext ctx, - Short origin, - BgpRouteEntry.AsPath asPath, - Long localPref, - MpNlri legacyNlri, - Collection<MpNlri> mpNlriReachList) - throws BgpMessage.BgpParseException { - boolean hasNlri = false; - boolean hasLegacyNlri = false; - - // - // Convenience flags that are used to check for missing attributes. - // - // NOTE: The hasLegacyNlri flag is always set to true if the - // Multiprotocol Extensions are not enabled, even if the UPDATE - // message doesn't contain the legacy NLRI (per RFC 4271). - // - if (!bgpSession.mpExtensions()) { - hasNlri = true; - hasLegacyNlri = true; - } else { - if (!legacyNlri.nlri4.isEmpty()) { - hasNlri = true; - hasLegacyNlri = true; - } - if (!mpNlriReachList.isEmpty()) { - hasNlri = true; - } - } - - // - // Check for Missing Well-known Attributes - // - if (hasNlri && ((origin == null) || (origin == -1))) { - // Missing Attribute Type Code ORIGIN - int type = BgpConstants.Update.Origin.TYPE; - actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type); - String errorMsg = "Missing Well-known Attribute: ORIGIN"; - throw new BgpMessage.BgpParseException(errorMsg); - } - if (hasNlri && (asPath == null)) { - // Missing Attribute Type Code AS_PATH - int type = BgpConstants.Update.AsPath.TYPE; - actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type); - String errorMsg = "Missing Well-known Attribute: AS_PATH"; - throw new BgpMessage.BgpParseException(errorMsg); - } - if (hasNlri && (localPref == null)) { - // Missing Attribute Type Code LOCAL_PREF - // NOTE: Required for iBGP - int type = BgpConstants.Update.LocalPref.TYPE; - actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type); - String errorMsg = "Missing Well-known Attribute: LOCAL_PREF"; - throw new BgpMessage.BgpParseException(errorMsg); - } - if (hasLegacyNlri && (legacyNlri.nextHop4 == null)) { - // Missing Attribute Type Code NEXT_HOP - int type = BgpConstants.Update.NextHop.TYPE; - actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type); - String errorMsg = "Missing Well-known Attribute: NEXT_HOP"; - throw new BgpMessage.BgpParseException(errorMsg); - } - } - - /** - * Verifies the BGP UPDATE Attribute Flags. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @throws BgpMessage.BgpParseException - */ - private static void verifyBgpUpdateAttributeFlags( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // - // Assign the Attribute Type Name and the Well-known flag - // - String typeName = "UNKNOWN"; - boolean isWellKnown = false; - switch (attrTypeCode) { - case BgpConstants.Update.Origin.TYPE: - isWellKnown = true; - typeName = "ORIGIN"; - break; - case BgpConstants.Update.AsPath.TYPE: - isWellKnown = true; - typeName = "AS_PATH"; - break; - case BgpConstants.Update.NextHop.TYPE: - isWellKnown = true; - typeName = "NEXT_HOP"; - break; - case BgpConstants.Update.MultiExitDisc.TYPE: - isWellKnown = false; - typeName = "MULTI_EXIT_DISC"; - break; - case BgpConstants.Update.LocalPref.TYPE: - isWellKnown = true; - typeName = "LOCAL_PREF"; - break; - case BgpConstants.Update.AtomicAggregate.TYPE: - isWellKnown = true; - typeName = "ATOMIC_AGGREGATE"; - break; - case BgpConstants.Update.Aggregator.TYPE: - isWellKnown = false; - typeName = "AGGREGATOR"; - break; - case BgpConstants.Update.MpReachNlri.TYPE: - isWellKnown = false; - typeName = "MP_REACH_NLRI"; - break; - case BgpConstants.Update.MpUnreachNlri.TYPE: - isWellKnown = false; - typeName = "MP_UNREACH_NLRI"; - break; - default: - isWellKnown = false; - typeName = "UNKNOWN(" + attrTypeCode + ")"; - break; - } - - // - // Verify the Attribute Flags - // - boolean optionalBit = ((0x80 & attrFlags) != 0); - boolean transitiveBit = ((0x40 & attrFlags) != 0); - boolean partialBit = ((0x20 & attrFlags) != 0); - if ((isWellKnown && optionalBit) || - (isWellKnown && (!transitiveBit)) || - (isWellKnown && partialBit) || - (optionalBit && (!transitiveBit) && partialBit)) { - // - // ERROR: The Optional bit cannot be set for Well-known attributes - // ERROR: The Transtive bit MUST be 1 for well-known attributes - // ERROR: The Partial bit MUST be 0 for well-known attributes - // ERROR: The Partial bit MUST be 0 for optional non-transitive - // attributes - // - actionsBgpUpdateAttributeFlagsError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Flags Error for " + typeName + ": " + - attrFlags; - throw new BgpMessage.BgpParseException(errorMsg); - } - } - - /** - * Parses BGP UPDATE Attribute Type ORIGIN. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed ORIGIN value - * @throws BgpMessage.BgpParseException - */ - private static short parseAttributeTypeOrigin( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // Check the Attribute Length - if (attrLen != BgpConstants.Update.Origin.LENGTH) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - message.markReaderIndex(); - short origin = message.readUnsignedByte(); - switch (origin) { - case BgpConstants.Update.Origin.IGP: - // FALLTHROUGH - case BgpConstants.Update.Origin.EGP: - // FALLTHROUGH - case BgpConstants.Update.Origin.INCOMPLETE: - break; - default: - // ERROR: Invalid ORIGIN Attribute - message.resetReaderIndex(); - actionsBgpUpdateInvalidOriginAttribute( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message, - origin); - String errorMsg = "Invalid ORIGIN Attribute: " + origin; - throw new BgpMessage.BgpParseException(errorMsg); - } - - return origin; - } - - /** - * Parses BGP UPDATE Attribute AS Path. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed AS Path - * @throws BgpMessage.BgpParseException - */ - private static BgpRouteEntry.AsPath parseAttributeTypeAsPath( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - - // - // Parse the message - // - while (attrLen > 0) { - if (attrLen < 2) { - // ERROR: Malformed AS_PATH - actionsBgpUpdateMalformedAsPath(bgpSession, ctx); - String errorMsg = "Malformed AS Path"; - throw new BgpMessage.BgpParseException(errorMsg); - } - // Get the Path Segment Type and Length (in number of ASes) - short pathSegmentType = message.readUnsignedByte(); - short pathSegmentLength = message.readUnsignedByte(); - attrLen -= 2; - - // Verify the Path Segment Type - switch (pathSegmentType) { - case BgpConstants.Update.AsPath.AS_SET: - // FALLTHROUGH - case BgpConstants.Update.AsPath.AS_SEQUENCE: - // FALLTHROUGH - case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE: - // FALLTHROUGH - case BgpConstants.Update.AsPath.AS_CONFED_SET: - break; - default: - // ERROR: Invalid Path Segment Type - // - // NOTE: The BGP Spec (RFC 4271) doesn't contain Error Subcode - // for "Invalid Path Segment Type", hence we return - // the error as "Malformed AS_PATH". - // - actionsBgpUpdateMalformedAsPath(bgpSession, ctx); - String errorMsg = - "Invalid AS Path Segment Type: " + pathSegmentType; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // 4-octet AS number handling. - int asPathLen; - if (bgpSession.isAs4OctetCapable()) { - asPathLen = BgpConstants.Update.AS_4OCTET_LENGTH; - } else { - asPathLen = BgpConstants.Update.AS_LENGTH; - } - - // Parse the AS numbers - if (asPathLen * pathSegmentLength > attrLen) { - // ERROR: Malformed AS_PATH - actionsBgpUpdateMalformedAsPath(bgpSession, ctx); - String errorMsg = "Malformed AS Path"; - throw new BgpMessage.BgpParseException(errorMsg); - } - attrLen -= (asPathLen * pathSegmentLength); - ArrayList<Long> segmentAsNumbers = new ArrayList<>(); - while (pathSegmentLength-- > 0) { - long asNumber; - if (asPathLen == BgpConstants.Update.AS_4OCTET_LENGTH) { - asNumber = message.readUnsignedInt(); - } else { - asNumber = message.readUnsignedShort(); - } - segmentAsNumbers.add(asNumber); - } - - BgpRouteEntry.PathSegment pathSegment = - new BgpRouteEntry.PathSegment((byte) pathSegmentType, - segmentAsNumbers); - pathSegments.add(pathSegment); - } - - return new BgpRouteEntry.AsPath(pathSegments); - } - - /** - * Parses BGP UPDATE Attribute Type NEXT_HOP. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed NEXT_HOP value - * @throws BgpMessage.BgpParseException - */ - private static Ip4Address parseAttributeTypeNextHop( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // Check the Attribute Length - if (attrLen != BgpConstants.Update.NextHop.LENGTH) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - message.markReaderIndex(); - Ip4Address nextHopAddress = - Ip4Address.valueOf((int) message.readUnsignedInt()); - // - // Check whether the NEXT_HOP IP address is semantically correct. - // As per RFC 4271, Section 6.3: - // - // a) It MUST NOT be the IP address of the receiving speaker - // b) In the case of an EBGP .... - // - // Here we check only (a), because (b) doesn't apply for us: all our - // peers are iBGP. - // - if (nextHopAddress.equals(bgpSession.localInfo().ip4Address())) { - // ERROR: Invalid NEXT_HOP Attribute - message.resetReaderIndex(); - actionsBgpUpdateInvalidNextHopAttribute( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message, - nextHopAddress); - String errorMsg = "Invalid NEXT_HOP Attribute: " + nextHopAddress; - throw new BgpMessage.BgpParseException(errorMsg); - } - - return nextHopAddress; - } - - /** - * Parses BGP UPDATE Attribute Type MULTI_EXIT_DISC. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed MULTI_EXIT_DISC value - * @throws BgpMessage.BgpParseException - */ - private static long parseAttributeTypeMultiExitDisc( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // Check the Attribute Length - if (attrLen != BgpConstants.Update.MultiExitDisc.LENGTH) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - long multiExitDisc = message.readUnsignedInt(); - return multiExitDisc; - } - - /** - * Parses BGP UPDATE Attribute Type LOCAL_PREF. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed LOCAL_PREF value - * @throws BgpMessage.BgpParseException - */ - private static long parseAttributeTypeLocalPref( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // Check the Attribute Length - if (attrLen != BgpConstants.Update.LocalPref.LENGTH) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - long localPref = message.readUnsignedInt(); - return localPref; - } - - /** - * Parses BGP UPDATE Attribute Type ATOMIC_AGGREGATE. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @throws BgpMessage.BgpParseException - */ - private static void parseAttributeTypeAtomicAggregate( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - - // Check the Attribute Length - if (attrLen != BgpConstants.Update.AtomicAggregate.LENGTH) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // Nothing to do: this attribute is primarily informational - } - - /** - * Parses BGP UPDATE Attribute Type AGGREGATOR. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed AGGREGATOR value: a tuple of <AS-Number, IP-Address> - * @throws BgpMessage.BgpParseException - */ - private static Pair<Long, Ip4Address> parseAttributeTypeAggregator( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - int expectedAttrLen; - - if (bgpSession.isAs4OctetCapable()) { - expectedAttrLen = BgpConstants.Update.Aggregator.AS4_LENGTH; - } else { - expectedAttrLen = BgpConstants.Update.Aggregator.AS2_LENGTH; - } - - // Check the Attribute Length - if (attrLen != expectedAttrLen) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // The AGGREGATOR AS number - long aggregatorAsNumber; - if (bgpSession.isAs4OctetCapable()) { - aggregatorAsNumber = message.readUnsignedInt(); - } else { - aggregatorAsNumber = message.readUnsignedShort(); - } - // The AGGREGATOR IP address - Ip4Address aggregatorIpAddress = - Ip4Address.valueOf((int) message.readUnsignedInt()); - - Pair<Long, Ip4Address> aggregator = Pair.of(aggregatorAsNumber, - aggregatorIpAddress); - return aggregator; - } - - /** - * Parses BGP UPDATE Attribute Type MP_REACH_NLRI. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed MP_REACH_NLRI information if recognized, otherwise - * null - * @throws BgpMessage.BgpParseException - */ - private static MpNlri parseAttributeTypeMpReachNlri( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - int attributeEnd = message.readerIndex() + attrLen; - - // Check the Attribute Length - if (attrLen < BgpConstants.Update.MpReachNlri.MIN_LENGTH) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - message.markReaderIndex(); - int afi = message.readUnsignedShort(); - int safi = message.readUnsignedByte(); - int nextHopLen = message.readUnsignedByte(); - - // - // Verify the AFI/SAFI, and skip the attribute if not recognized. - // NOTE: Currently, we support only IPv4/IPv6 UNICAST - // - if (((afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4) && - (afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6)) || - (safi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST)) { - // Skip the attribute - message.resetReaderIndex(); - message.skipBytes(attrLen); - return null; - } - - // - // Verify the next-hop length - // - int expectedNextHopLen = 0; - switch (afi) { - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4: - expectedNextHopLen = Ip4Address.BYTE_LENGTH; - break; - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6: - expectedNextHopLen = Ip6Address.BYTE_LENGTH; - break; - default: - // UNREACHABLE - break; - } - if (nextHopLen != expectedNextHopLen) { - // ERROR: Optional Attribute Error - message.resetReaderIndex(); - actionsBgpUpdateOptionalAttributeError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Invalid next-hop network address length. " + - "Received " + nextHopLen + " expected " + expectedNextHopLen; - throw new BgpMessage.BgpParseException(errorMsg); - } - // NOTE: We use "+ 1" to take into account the Reserved field (1 octet) - if (message.readerIndex() + nextHopLen + 1 >= attributeEnd) { - // ERROR: Optional Attribute Error - message.resetReaderIndex(); - actionsBgpUpdateOptionalAttributeError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Malformed next-hop network address"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - // - // Get the Next-hop address, skip the Reserved field, and get the NLRI - // - byte[] nextHopBuffer = new byte[nextHopLen]; - message.readBytes(nextHopBuffer, 0, nextHopLen); - int reserved = message.readUnsignedByte(); - MpNlri mpNlri = new MpNlri(afi, safi); - try { - switch (afi) { - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4: - // The next-hop address - mpNlri.nextHop4 = Ip4Address.valueOf(nextHopBuffer); - // The NLRI - mpNlri.nlri4 = parsePackedIp4Prefixes( - attributeEnd - message.readerIndex(), - message); - break; - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6: - // The next-hop address - mpNlri.nextHop6 = Ip6Address.valueOf(nextHopBuffer); - // The NLRI - mpNlri.nlri6 = parsePackedIp6Prefixes( - attributeEnd - message.readerIndex(), - message); - break; - default: - // UNREACHABLE - break; - } - } catch (BgpMessage.BgpParseException e) { - // ERROR: Optional Attribute Error - message.resetReaderIndex(); - actionsBgpUpdateOptionalAttributeError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Malformed network layer reachability information"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - return mpNlri; - } - - /** - * Parses BGP UPDATE Attribute Type MP_UNREACH_NLRI. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message to parse - * @return the parsed MP_UNREACH_NLRI information if recognized, otherwise - * null - * @throws BgpMessage.BgpParseException - */ - private static MpNlri parseAttributeTypeMpUnreachNlri( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - int attributeEnd = message.readerIndex() + attrLen; - - // Check the Attribute Length - if (attrLen < BgpConstants.Update.MpUnreachNlri.MIN_LENGTH) { - // ERROR: Attribute Length Error - actionsBgpUpdateAttributeLengthError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Attribute Length Error"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - message.markReaderIndex(); - int afi = message.readUnsignedShort(); - int safi = message.readUnsignedByte(); - - // - // Verify the AFI/SAFI, and skip the attribute if not recognized. - // NOTE: Currently, we support only IPv4/IPv6 UNICAST - // - if (((afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4) && - (afi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6)) || - (safi != BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST)) { - // Skip the attribute - message.resetReaderIndex(); - message.skipBytes(attrLen); - return null; - } - - // - // Get the Withdrawn Routes - // - MpNlri mpNlri = new MpNlri(afi, safi); - try { - switch (afi) { - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4: - // The Withdrawn Routes - mpNlri.nlri4 = parsePackedIp4Prefixes( - attributeEnd - message.readerIndex(), - message); - break; - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6: - // The Withdrawn Routes - mpNlri.nlri6 = parsePackedIp6Prefixes( - attributeEnd - message.readerIndex(), - message); - break; - default: - // UNREACHABLE - break; - } - } catch (BgpMessage.BgpParseException e) { - // ERROR: Optional Attribute Error - message.resetReaderIndex(); - actionsBgpUpdateOptionalAttributeError( - bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message); - String errorMsg = "Malformed withdrawn routes"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - return mpNlri; - } - - /** - * Parses a message that contains encoded IPv4 network prefixes. - * <p> - * The IPv4 prefixes are encoded in the form: - * <Length, Prefix> where Length is the length in bits of the IPv4 prefix, - * and Prefix is the IPv4 prefix (padded with trailing bits to the end - * of an octet). - * - * @param totalLength the total length of the data to parse - * @param message the message with data to parse - * @return a collection of parsed IPv4 network prefixes - * @throws BgpMessage.BgpParseException - */ - private static Collection<Ip4Prefix> parsePackedIp4Prefixes( - int totalLength, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - Collection<Ip4Prefix> result = new ArrayList<>(); - - if (totalLength == 0) { - return result; - } - - // Parse the data - byte[] buffer = new byte[Ip4Address.BYTE_LENGTH]; - int dataEnd = message.readerIndex() + totalLength; - while (message.readerIndex() < dataEnd) { - int prefixBitlen = message.readUnsignedByte(); - int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up - if (message.readerIndex() + prefixBytelen > dataEnd) { - String errorMsg = "Malformed Network Prefixes"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - message.readBytes(buffer, 0, prefixBytelen); - Ip4Prefix prefix = Ip4Prefix.valueOf(Ip4Address.valueOf(buffer), - prefixBitlen); - result.add(prefix); - } - - return result; - } - - /** - * Parses a message that contains encoded IPv6 network prefixes. - * <p> - * The IPv6 prefixes are encoded in the form: - * <Length, Prefix> where Length is the length in bits of the IPv6 prefix, - * and Prefix is the IPv6 prefix (padded with trailing bits to the end - * of an octet). - * - * @param totalLength the total length of the data to parse - * @param message the message with data to parse - * @return a collection of parsed IPv6 network prefixes - * @throws BgpMessage.BgpParseException - */ - private static Collection<Ip6Prefix> parsePackedIp6Prefixes( - int totalLength, - ChannelBuffer message) - throws BgpMessage.BgpParseException { - Collection<Ip6Prefix> result = new ArrayList<>(); - - if (totalLength == 0) { - return result; - } - - // Parse the data - byte[] buffer = new byte[Ip6Address.BYTE_LENGTH]; - int dataEnd = message.readerIndex() + totalLength; - while (message.readerIndex() < dataEnd) { - int prefixBitlen = message.readUnsignedByte(); - int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up - if (message.readerIndex() + prefixBytelen > dataEnd) { - String errorMsg = "Malformed Network Prefixes"; - throw new BgpMessage.BgpParseException(errorMsg); - } - - message.readBytes(buffer, 0, prefixBytelen); - Ip6Prefix prefix = Ip6Prefix.valueOf(Ip6Address.valueOf(buffer), - prefixBitlen); - result.add(prefix); - } - - return result; - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Invalid Network Field Error: send NOTIFICATION and close the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - */ - private static void actionsBgpUpdateInvalidNetworkField( - BgpSession bgpSession, - ChannelHandlerContext ctx) { - log.debug("BGP RX UPDATE Error from {}: Invalid Network Field", - bgpSession.remoteInfo().address()); - - // - // ERROR: Invalid Network Field - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_NETWORK_FIELD; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Malformed Attribute List Error: send NOTIFICATION and close the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - */ - private static void actionsBgpUpdateMalformedAttributeList( - BgpSession bgpSession, - ChannelHandlerContext ctx) { - log.debug("BGP RX UPDATE Error from {}: Malformed Attribute List", - bgpSession.remoteInfo().address()); - - // - // ERROR: Malformed Attribute List - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MALFORMED_ATTRIBUTE_LIST; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Missing Well-known Attribute Error: send NOTIFICATION and close the - * channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param missingAttrTypeCode the missing attribute type code - */ - private static void actionsBgpUpdateMissingWellKnownAttribute( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int missingAttrTypeCode) { - log.debug("BGP RX UPDATE Error from {}: Missing Well-known Attribute: {}", - bgpSession.remoteInfo().address(), missingAttrTypeCode); - - // - // ERROR: Missing Well-known Attribute - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MISSING_WELL_KNOWN_ATTRIBUTE; - ChannelBuffer data = ChannelBuffers.buffer(1); - data.writeByte(missingAttrTypeCode); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Invalid ORIGIN Attribute Error: send NOTIFICATION and close the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message with the data - * @param origin the ORIGIN attribute value - */ - private static void actionsBgpUpdateInvalidOriginAttribute( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message, - short origin) { - log.debug("BGP RX UPDATE Error from {}: Invalid ORIGIN Attribute", - bgpSession.remoteInfo().address()); - - // - // ERROR: Invalid ORIGIN Attribute - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_ORIGIN_ATTRIBUTE; - ChannelBuffer data = - prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen, - attrFlags, message); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Attribute Flags Error: send NOTIFICATION and close the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message with the data - */ - private static void actionsBgpUpdateAttributeFlagsError( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) { - log.debug("BGP RX UPDATE Error from {}: Attribute Flags Error", - bgpSession.remoteInfo().address()); - - // - // ERROR: Attribute Flags Error - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.ATTRIBUTE_FLAGS_ERROR; - ChannelBuffer data = - prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen, - attrFlags, message); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Invalid NEXT_HOP Attribute Error: send NOTIFICATION and close the - * channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message with the data - * @param nextHop the NEXT_HOP attribute value - */ - private static void actionsBgpUpdateInvalidNextHopAttribute( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message, - Ip4Address nextHop) { - log.debug("BGP RX UPDATE Error from {}: Invalid NEXT_HOP Attribute {}", - bgpSession.remoteInfo().address(), nextHop); - - // - // ERROR: Invalid NEXT_HOP Attribute - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.INVALID_NEXT_HOP_ATTRIBUTE; - ChannelBuffer data = - prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen, - attrFlags, message); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Unrecognized Well-known Attribute Error: send NOTIFICATION and close - * the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message with the data - */ - private static void actionsBgpUpdateUnrecognizedWellKnownAttribute( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) { - log.debug("BGP RX UPDATE Error from {}: " + - "Unrecognized Well-known Attribute Error: {}", - bgpSession.remoteInfo().address(), attrTypeCode); - - // - // ERROR: Unrecognized Well-known Attribute - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = - BgpConstants.Notifications.UpdateMessageError.UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE; - ChannelBuffer data = - prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen, - attrFlags, message); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Optional Attribute Error: send NOTIFICATION and close - * the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message with the data - */ - private static void actionsBgpUpdateOptionalAttributeError( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) { - log.debug("BGP RX UPDATE Error from {}: Optional Attribute Error: {}", - bgpSession.remoteInfo().address(), attrTypeCode); - - // - // ERROR: Optional Attribute Error - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = - BgpConstants.Notifications.UpdateMessageError.OPTIONAL_ATTRIBUTE_ERROR; - ChannelBuffer data = - prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen, - attrFlags, message); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Attribute Length Error: send NOTIFICATION and close the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message with the data - */ - private static void actionsBgpUpdateAttributeLengthError( - BgpSession bgpSession, - ChannelHandlerContext ctx, - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) { - log.debug("BGP RX UPDATE Error from {}: Attribute Length Error", - bgpSession.remoteInfo().address()); - - // - // ERROR: Attribute Length Error - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.ATTRIBUTE_LENGTH_ERROR; - ChannelBuffer data = - prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen, - attrFlags, message); - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - data); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Applies the appropriate actions after detecting BGP UPDATE - * Malformed AS_PATH Error: send NOTIFICATION and close the channel. - * - * @param bgpSession the BGP Session to use - * @param ctx the Channel Handler Context - */ - private static void actionsBgpUpdateMalformedAsPath( - BgpSession bgpSession, - ChannelHandlerContext ctx) { - log.debug("BGP RX UPDATE Error from {}: Malformed AS Path", - bgpSession.remoteInfo().address()); - - // - // ERROR: Malformed AS_PATH - // - // Send NOTIFICATION and close the connection - int errorCode = BgpConstants.Notifications.UpdateMessageError.ERROR_CODE; - int errorSubcode = BgpConstants.Notifications.UpdateMessageError.MALFORMED_AS_PATH; - ChannelBuffer txMessage = - BgpNotification.prepareBgpNotification(errorCode, errorSubcode, - null); - ctx.getChannel().write(txMessage); - bgpSession.closeSession(ctx); - } - - /** - * Prepares BGP UPDATE Notification data payload. - * - * @param attrTypeCode the attribute type code - * @param attrLen the attribute length (in octets) - * @param attrFlags the attribute flags - * @param message the message with the data - * @return the buffer with the data payload for the BGP UPDATE Notification - */ - private static ChannelBuffer prepareBgpUpdateNotificationDataPayload( - int attrTypeCode, - int attrLen, - int attrFlags, - ChannelBuffer message) { - // Compute the attribute length field octets - boolean extendedLengthBit = ((0x10 & attrFlags) != 0); - int attrLenOctets = 1; - if (extendedLengthBit) { - attrLenOctets = 2; - } - ChannelBuffer data = - ChannelBuffers.buffer(attrLen + attrLenOctets + 1); - data.writeByte(attrTypeCode); - if (extendedLengthBit) { - data.writeShort(attrLen); - } else { - data.writeByte(attrLen); - } - data.writeBytes(message, attrLen); - return data; - } - - /** - * Helper class for storing Multiprotocol Network Layer Reachability - * information. - */ - private static final class MpNlri { - private final int afi; - private final int safi; - private Ip4Address nextHop4; - private Ip6Address nextHop6; - private Collection<Ip4Prefix> nlri4 = new ArrayList<>(); - private Collection<Ip6Prefix> nlri6 = new ArrayList<>(); - - /** - * Constructor. - * - * @param afi the Address Family Identifier - * @param safi the Subsequent Address Family Identifier - */ - private MpNlri(int afi, int safi) { - this.afi = afi; - this.safi = safi; - } - } - - /** - * Helper class for storing decoded BGP routing information. - */ - private static final class DecodedBgpRoutes { - private final Map<Ip4Prefix, BgpRouteEntry> addedUnicastRoutes4 = - new HashMap<>(); - private final Map<Ip6Prefix, BgpRouteEntry> addedUnicastRoutes6 = - new HashMap<>(); - private final Map<Ip4Prefix, BgpRouteEntry> deletedUnicastRoutes4 = - new HashMap<>(); - private final Map<Ip6Prefix, BgpRouteEntry> deletedUnicastRoutes6 = - new HashMap<>(); - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java deleted file mode 100644 index 031111b2..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/bgp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2014-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. - */ - -/** - * Implementation of the BGP protocol. - */ -package org.onosproject.routing.bgp; diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/AddRouteCommand.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/AddRouteCommand.java deleted file mode 100644 index 452a145e..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/AddRouteCommand.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.routing.cli; - -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.routing.FibEntry; -import org.onosproject.routing.FibListener; -import org.onosproject.routing.FibUpdate; -import org.onosproject.routing.StaticRoutingService; - -import java.util.Arrays; -import java.util.Collections; - -@Command(scope = "onos", name = "add-route", description = "Installs static route") -public class AddRouteCommand extends AbstractShellCommand { - - @Argument(index = 0, name = "prefix IP MAC", - description = "prefix nexthopIP nexthopMAC", - required = true, multiValued = true) - String[] fibEntryString = null; - - @Override - protected void execute() { - StaticRoutingService routingService = get(StaticRoutingService.class); - - if (fibEntryString.length < 3) { - return; - } - - IpPrefix prefix = IpPrefix.valueOf(fibEntryString[0]); - IpAddress nextHopIp = IpAddress.valueOf(fibEntryString[1]); - MacAddress nextHopMac = MacAddress.valueOf(fibEntryString[2]); - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, nextHopMac); - FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry); - - FibListener fibListener = routingService.getFibListener(); - fibListener.update(Arrays.asList(fibUpdate), Collections.emptyList()); - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java deleted file mode 100644 index 875a339a..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpNeighborsListCommand.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2014-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.routing.cli; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.apache.karaf.shell.commands.Command; -import org.apache.karaf.shell.commands.Option; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.routing.bgp.BgpInfoService; -import org.onosproject.routing.bgp.BgpSession; - -import java.util.Collection; - -/** - * Command to show the BGP neighbors. - */ -@Command(scope = "onos", name = "bgp-neighbors", - description = "Lists the BGP neighbors") -public class BgpNeighborsListCommand extends AbstractShellCommand { - @Option(name = "-n", aliases = "--neighbor", - description = "BGP neighbor to display information about", - required = false, multiValued = false) - private String bgpNeighbor; - - private static final String FORMAT_NEIGHBOR_LINE1 = - "BGP neighbor is %s, remote AS %d, local AS %d"; - private static final String FORMAT_NEIGHBOR_LINE2 = - " Remote router ID %s, IP %s, BGP version %d, Hold time %d"; - private static final String FORMAT_NEIGHBOR_LINE3 = - " Remote AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s"; - private static final String FORMAT_NEIGHBOR_LINE4 = - " Local router ID %s, IP %s, BGP version %d, Hold time %d"; - private static final String FORMAT_NEIGHBOR_LINE5 = - " Local AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s"; - private static final String FORMAT_NEIGHBOR_LINE6 = - " 4 Octet AS Capability: %s %s"; - - @Override - protected void execute() { - BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class); - Collection<BgpSession> bgpSessions = service.getBgpSessions(); - - if (bgpNeighbor != null) { - // Print a single neighbor (if found) - BgpSession foundBgpSession = null; - for (BgpSession bgpSession : bgpSessions) { - if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) { - foundBgpSession = bgpSession; - break; - } - } - if (foundBgpSession != null) { - printNeighbor(foundBgpSession); - } else { - print("BGP neighbor %s not found", bgpNeighbor); - } - return; - } - - // Print all neighbors - printNeighbors(bgpSessions); - } - - /** - * Prints all BGP neighbors. - * - * @param bgpSessions the BGP sessions for the neighbors to print - */ - private void printNeighbors(Collection<BgpSession> bgpSessions) { - if (outputJson()) { - print("%s", json(bgpSessions)); - } else { - for (BgpSession bgpSession : bgpSessions) { - printNeighbor(bgpSession); - } - } - } - - /** - * Prints a BGP neighbor. - * - * @param bgpSession the BGP session for the neighbor to print - */ - private void printNeighbor(BgpSession bgpSession) { - print(FORMAT_NEIGHBOR_LINE1, - bgpSession.remoteInfo().bgpId().toString(), - bgpSession.remoteInfo().asNumber(), - bgpSession.localInfo().asNumber()); - print(FORMAT_NEIGHBOR_LINE2, - bgpSession.remoteInfo().bgpId().toString(), - bgpSession.remoteInfo().address().toString(), - bgpSession.remoteInfo().bgpVersion(), - bgpSession.remoteInfo().holdtime()); - print(FORMAT_NEIGHBOR_LINE3, - bgpSession.remoteInfo().ipv4Unicast() ? "YES" : "NO", - bgpSession.remoteInfo().ipv4Multicast() ? "YES" : "NO", - bgpSession.remoteInfo().ipv6Unicast() ? "YES" : "NO", - bgpSession.remoteInfo().ipv6Multicast() ? "YES" : "NO"); - print(FORMAT_NEIGHBOR_LINE4, - bgpSession.localInfo().bgpId().toString(), - bgpSession.localInfo().address().toString(), - bgpSession.localInfo().bgpVersion(), - bgpSession.localInfo().holdtime()); - print(FORMAT_NEIGHBOR_LINE5, - bgpSession.localInfo().ipv4Unicast() ? "YES" : "NO", - bgpSession.localInfo().ipv4Multicast() ? "YES" : "NO", - bgpSession.localInfo().ipv6Unicast() ? "YES" : "NO", - bgpSession.localInfo().ipv6Multicast() ? "YES" : "NO"); - if (bgpSession.localInfo().as4OctetCapability() || - bgpSession.remoteInfo().as4OctetCapability()) { - print(FORMAT_NEIGHBOR_LINE6, - bgpSession.localInfo().as4OctetCapability() ? "Advertised" : "", - bgpSession.remoteInfo().as4OctetCapability() ? "Received" : ""); - } - } - - /** - * Produces a JSON array of BGP neighbors. - * - * @param bgpSessions the BGP sessions with the data - * @return JSON array with the neighbors - */ - private JsonNode json(Collection<BgpSession> bgpSessions) { - ObjectMapper mapper = new ObjectMapper(); - ArrayNode result = mapper.createArrayNode(); - - for (BgpSession bgpSession : bgpSessions) { - result.add(json(mapper, bgpSession)); - } - return result; - } - - /** - * Produces JSON object for a BGP neighbor. - * - * @param mapper the JSON object mapper to use - * @param bgpSession the BGP session with the data - * @return JSON object for the route - */ - private ObjectNode json(ObjectMapper mapper, BgpSession bgpSession) { - ObjectNode result = mapper.createObjectNode(); - - result.put("remoteAddress", bgpSession.remoteInfo().address().toString()); - result.put("remoteBgpVersion", bgpSession.remoteInfo().bgpVersion()); - result.put("remoteAs", bgpSession.remoteInfo().asNumber()); - result.put("remoteAs4", bgpSession.remoteInfo().as4Number()); - result.put("remoteHoldtime", bgpSession.remoteInfo().holdtime()); - result.put("remoteBgpId", bgpSession.remoteInfo().bgpId().toString()); - result.put("remoteIpv4Unicast", bgpSession.remoteInfo().ipv4Unicast()); - result.put("remoteIpv4Multicast", bgpSession.remoteInfo().ipv4Multicast()); - result.put("remoteIpv6Unicast", bgpSession.remoteInfo().ipv6Unicast()); - result.put("remoteIpv6Multicast", bgpSession.remoteInfo().ipv6Multicast()); - // - result.put("localAddress", bgpSession.localInfo().address().toString()); - result.put("localBgpVersion", bgpSession.localInfo().bgpVersion()); - result.put("localAs", bgpSession.localInfo().asNumber()); - result.put("localAs4", bgpSession.localInfo().as4Number()); - result.put("localHoldtime", bgpSession.localInfo().holdtime()); - result.put("localBgpId", bgpSession.localInfo().bgpId().toString()); - result.put("localIpv4Unicast", bgpSession.localInfo().ipv4Unicast()); - result.put("localIpv4Multicast", bgpSession.localInfo().ipv4Multicast()); - result.put("localIpv6Unicast", bgpSession.localInfo().ipv6Unicast()); - result.put("localIpv6Multicast", bgpSession.localInfo().ipv6Multicast()); - - return result; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java deleted file mode 100644 index ab8e975a..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 2014-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.routing.cli; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.apache.karaf.shell.commands.Command; -import org.apache.karaf.shell.commands.Option; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.routing.bgp.BgpInfoService; -import org.onosproject.routing.bgp.BgpRouteEntry; -import org.onosproject.routing.bgp.BgpSession; -import org.onosproject.routing.bgp.BgpConstants; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * Command to show the routes learned through BGP. - */ -@Command(scope = "onos", name = "bgp-routes", - description = "Lists all BGP best routes") -public class BgpRoutesListCommand extends AbstractShellCommand { - @Option(name = "-s", aliases = "--summary", - description = "BGP routes summary", - required = false, multiValued = false) - private boolean routesSummary = false; - - @Option(name = "-n", aliases = "--neighbor", - description = "Routes from a BGP neighbor", - required = false, multiValued = false) - private String bgpNeighbor; - - private static final String FORMAT_SUMMARY_V4 = - "Total BGP IPv4 routes = %d"; - private static final String FORMAT_SUMMARY_V6 = - "Total BGP IPv6 routes = %d"; - private static final String FORMAT_HEADER = - " Network Next Hop Origin LocalPref MED BGP-ID"; - private static final String FORMAT_ROUTE_LINE1 = - " %-18s %-15s %6s %9s %9s %-15s"; - private static final String FORMAT_ROUTE_LINE2 = - " AsPath %s"; - - @Override - protected void execute() { - BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class); - - // Print summary of the routes - if (routesSummary) { - printSummary(service.getBgpRoutes4(), service.getBgpRoutes6()); - return; - } - - BgpSession foundBgpSession = null; - if (bgpNeighbor != null) { - // Print the routes from a single neighbor (if found) - for (BgpSession bgpSession : service.getBgpSessions()) { - if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) { - foundBgpSession = bgpSession; - break; - } - } - if (foundBgpSession == null) { - print("BGP neighbor %s not found", bgpNeighbor); - return; - } - } - - // Print the routes - if (foundBgpSession != null) { - printRoutes(foundBgpSession.getBgpRibIn4(), - foundBgpSession.getBgpRibIn6()); - } else { - printRoutes(service.getBgpRoutes4(), service.getBgpRoutes6()); - } - } - - /** - * Prints summary of the routes. - * - * @param routes4 the IPv4 routes - * @param routes6 the IPv6 routes - */ - private void printSummary(Collection<BgpRouteEntry> routes4, - Collection<BgpRouteEntry> routes6) { - if (outputJson()) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode result = mapper.createObjectNode(); - result.put("totalRoutes4", routes4.size()); - result.put("totalRoutes6", routes6.size()); - print("%s", result); - } else { - print(FORMAT_SUMMARY_V4, routes4.size()); - print(FORMAT_SUMMARY_V6, routes6.size()); - } - } - - /** - * Prints all routes. - * - * @param routes4 the IPv4 routes to print - * @param routes6 the IPv6 routes to print - */ - private void printRoutes(Collection<BgpRouteEntry> routes4, - Collection<BgpRouteEntry> routes6) { - if (outputJson()) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode result = mapper.createObjectNode(); - result.set("routes4", json(routes4)); - result.set("routes6", json(routes6)); - print("%s", result); - } else { - // The IPv4 routes - print(FORMAT_HEADER); - for (BgpRouteEntry route : routes4) { - printRoute(route); - } - print(FORMAT_SUMMARY_V4, routes4.size()); - print(""); // Empty separator line - // The IPv6 routes - print(FORMAT_HEADER); - for (BgpRouteEntry route : routes6) { - printRoute(route); - } - print(FORMAT_SUMMARY_V6, routes6.size()); - } - } - - /** - * Prints a BGP route. - * - * @param route the route to print - */ - private void printRoute(BgpRouteEntry route) { - if (route != null) { - print(FORMAT_ROUTE_LINE1, route.prefix(), route.nextHop(), - BgpConstants.Update.Origin.typeToString(route.getOrigin()), - route.getLocalPref(), route.getMultiExitDisc(), - route.getBgpSession().remoteInfo().bgpId()); - print(FORMAT_ROUTE_LINE2, asPath4Cli(route.getAsPath())); - } - } - - /** - * Formats the AS Path as a string that can be shown on the CLI. - * - * @param asPath the AS Path to format - * @return the AS Path as a string - */ - private String asPath4Cli(BgpRouteEntry.AsPath asPath) { - ArrayList<BgpRouteEntry.PathSegment> pathSegments = - asPath.getPathSegments(); - - if (pathSegments.isEmpty()) { - return "[none]"; - } - - final StringBuilder builder = new StringBuilder(); - for (BgpRouteEntry.PathSegment pathSegment : pathSegments) { - String prefix = null; - String suffix = null; - switch (pathSegment.getType()) { - case BgpConstants.Update.AsPath.AS_SET: - prefix = "[AS-Set"; - suffix = "]"; - break; - case BgpConstants.Update.AsPath.AS_SEQUENCE: - break; - case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE: - prefix = "[AS-Confed-Seq"; - suffix = "]"; - break; - case BgpConstants.Update.AsPath.AS_CONFED_SET: - prefix = "[AS-Confed-Set"; - suffix = "]"; - break; - default: - builder.append(String.format("(type = %s)", - BgpConstants.Update.AsPath.typeToString(pathSegment.getType()))); - break; - } - - if (prefix != null) { - if (builder.length() > 0) { - builder.append(" "); // Separator - } - builder.append(prefix); - } - // Print the AS numbers - for (Long asn : pathSegment.getSegmentAsNumbers()) { - if (builder.length() > 0) { - builder.append(" "); // Separator - } - builder.append(String.format("%d", asn)); - } - if (suffix != null) { - // No need for separator - builder.append(prefix); - } - } - return builder.toString(); - } - - /** - * Produces a JSON array of routes. - * - * @param routes the routes with the data - * @return JSON array with the routes - */ - private JsonNode json(Collection<BgpRouteEntry> routes) { - ObjectMapper mapper = new ObjectMapper(); - ArrayNode result = mapper.createArrayNode(); - - for (BgpRouteEntry route : routes) { - result.add(json(mapper, route)); - } - return result; - } - - /** - * Produces JSON object for a route. - * - * @param mapper the JSON object mapper to use - * @param route the route with the data - * @return JSON object for the route - */ - private ObjectNode json(ObjectMapper mapper, BgpRouteEntry route) { - ObjectNode result = mapper.createObjectNode(); - - result.put("prefix", route.prefix().toString()); - result.put("nextHop", route.nextHop().toString()); - result.put("bgpId", - route.getBgpSession().remoteInfo().bgpId().toString()); - result.put("origin", BgpConstants.Update.Origin.typeToString(route.getOrigin())); - result.set("asPath", json(mapper, route.getAsPath())); - result.put("localPref", route.getLocalPref()); - result.put("multiExitDisc", route.getMultiExitDisc()); - - return result; - } - - /** - * Produces JSON object for an AS path. - * - * @param mapper the JSON object mapper to use - * @param asPath the AS path with the data - * @return JSON object for the AS path - */ - private ObjectNode json(ObjectMapper mapper, BgpRouteEntry.AsPath asPath) { - ObjectNode result = mapper.createObjectNode(); - ArrayNode pathSegmentsJson = mapper.createArrayNode(); - for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) { - ObjectNode pathSegmentJson = mapper.createObjectNode(); - pathSegmentJson.put("type", - BgpConstants.Update.AsPath.typeToString(pathSegment.getType())); - ArrayNode segmentAsNumbersJson = mapper.createArrayNode(); - for (Long asNumber : pathSegment.getSegmentAsNumbers()) { - segmentAsNumbersJson.add(asNumber); - } - pathSegmentJson.set("segmentAsNumbers", segmentAsNumbersJson); - pathSegmentsJson.add(pathSegmentJson); - } - result.set("pathSegments", pathSegmentsJson); - - return result; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpSpeakersListCommand.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpSpeakersListCommand.java deleted file mode 100644 index 064080fd..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/BgpSpeakersListCommand.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.routing.cli; - -import com.google.common.collect.Lists; -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.cli.Comparators; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.net.config.NetworkConfigService; -import org.onosproject.routing.RoutingService; -import org.onosproject.routing.config.BgpConfig; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * Lists the BGP speakers configured in the system. - */ -@Command(scope = "onos", name = "bgp-speakers", - description = "Lists all BGP speakers") -public class BgpSpeakersListCommand extends AbstractShellCommand { - - private static final String FORMAT = "port=%s/%s, peers=%s"; - private static final String NAME_FORMAT = "%s: " + FORMAT; - - private static final Comparator<BgpConfig.BgpSpeakerConfig> SPEAKERS_COMPARATOR = (s1, s2) -> - Comparators.CONNECT_POINT_COMPARATOR.compare(s1.connectPoint(), s2.connectPoint()); - - @Override - protected void execute() { - NetworkConfigService configService = get(NetworkConfigService.class); - CoreService coreService = get(CoreService.class); - ApplicationId appId = coreService.getAppId(RoutingService.ROUTER_APP_ID); - - BgpConfig config = configService.getConfig(appId, BgpConfig.class); - if (config == null) { - print("No speakers configured"); - return; - } - - List<BgpConfig.BgpSpeakerConfig> bgpSpeakers = - Lists.newArrayList(config.bgpSpeakers()); - - Collections.sort(bgpSpeakers, SPEAKERS_COMPARATOR); - - if (config.bgpSpeakers().isEmpty()) { - print("No speakers configured"); - } else { - bgpSpeakers.forEach( - s -> { - if (s.name().isPresent()) { - print(NAME_FORMAT, s.name().get(), s.connectPoint().deviceId(), - s.connectPoint().port(), s.peers()); - } else { - print(FORMAT, s.connectPoint().deviceId(), - s.connectPoint().port(), s.peers()); - } - }); - } - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/RemoveRouteCommand.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/RemoveRouteCommand.java deleted file mode 100644 index 3e216f95..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/RemoveRouteCommand.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.routing.cli; - -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.routing.FibEntry; -import org.onosproject.routing.FibListener; -import org.onosproject.routing.FibUpdate; -import org.onosproject.routing.StaticRoutingService; - -import java.util.Arrays; -import java.util.Collections; - -@Command(scope = "onos", name = "remove-route", description = "Removes static route") -public class RemoveRouteCommand extends AbstractShellCommand { - @Argument(index = 0, name = "prefix IP MAC", - description = "prefix nexthopIP nexthopMAC", - required = true, multiValued = true) - String[] fibEntryString = null; - - @Override - protected void execute() { - StaticRoutingService routingService = get(StaticRoutingService.class); - - if (fibEntryString.length < 3) { - return; - } - - IpPrefix prefix = IpPrefix.valueOf(fibEntryString[0]); - IpAddress nextHopIp = IpAddress.valueOf(fibEntryString[1]); - MacAddress nextHopMac = MacAddress.valueOf(fibEntryString[2]); - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, nextHopMac); - FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry); - - FibListener fibListener = routingService.getFibListener(); - fibListener.update(Collections.emptyList(), Arrays.asList(fibUpdate)); - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java deleted file mode 100644 index 04fcb8ff..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/RoutesListCommand.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2014-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.routing.cli; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.apache.karaf.shell.commands.Command; -import org.apache.karaf.shell.commands.Option; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.routing.RouteEntry; -import org.onosproject.routing.RoutingService; - -import java.util.Collection; - -/** - * Command to show the list of routes in SDN-IP's routing table. - */ -@Command(scope = "onos", name = "routes", - description = "Lists all SDN-IP best routes") -public class RoutesListCommand extends AbstractShellCommand { - @Option(name = "-s", aliases = "--summary", - description = "SDN-IP routes summary", - required = false, multiValued = false) - private boolean routesSummary = false; - - private static final String FORMAT_SUMMARY_V4 = - "Total SDN-IP IPv4 routes = %d"; - private static final String FORMAT_SUMMARY_V6 = - "Total SDN-IP IPv6 routes = %d"; - private static final String FORMAT_HEADER = - " Network Next Hop"; - private static final String FORMAT_ROUTE = - " %-18s %-15s"; - - @Override - protected void execute() { - RoutingService service = AbstractShellCommand.get(RoutingService.class); - - // Print summary of the routes - if (routesSummary) { - printSummary(service.getRoutes4(), service.getRoutes6()); - return; - } - - // Print all routes - printRoutes(service.getRoutes4(), service.getRoutes6()); - } - - /** - * Prints summary of the routes. - * - * @param routes4 the IPv4 routes - * @param routes6 the IPv6 routes - */ - private void printSummary(Collection<RouteEntry> routes4, - Collection<RouteEntry> routes6) { - if (outputJson()) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode result = mapper.createObjectNode(); - result.put("totalRoutes4", routes4.size()); - result.put("totalRoutes6", routes6.size()); - print("%s", result); - } else { - print(FORMAT_SUMMARY_V4, routes4.size()); - print(FORMAT_SUMMARY_V6, routes6.size()); - } - } - - /** - * Prints all routes. - * - * @param routes4 the IPv4 routes to print - * @param routes6 the IPv6 routes to print - */ - private void printRoutes(Collection<RouteEntry> routes4, - Collection<RouteEntry> routes6) { - if (outputJson()) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode result = mapper.createObjectNode(); - result.set("routes4", json(routes4)); - result.set("routes6", json(routes6)); - print("%s", result); - } else { - // The IPv4 routes - print(FORMAT_HEADER); - for (RouteEntry route : routes4) { - printRoute(route); - } - print(FORMAT_SUMMARY_V4, routes4.size()); - print(""); // Empty separator line - // The IPv6 routes - print(FORMAT_HEADER); - for (RouteEntry route : routes6) { - printRoute(route); - } - print(FORMAT_SUMMARY_V6, routes6.size()); - } - } - - /** - * Prints a route. - * - * @param route the route to print - */ - private void printRoute(RouteEntry route) { - if (route != null) { - print(FORMAT_ROUTE, route.prefix(), route.nextHop()); - } - } - - /** - * Produces a JSON array of routes. - * - * @param routes the routes with the data - * @return JSON array with the routes - */ - private JsonNode json(Collection<RouteEntry> routes) { - ObjectMapper mapper = new ObjectMapper(); - ArrayNode result = mapper.createArrayNode(); - - for (RouteEntry route : routes) { - result.add(json(mapper, route)); - } - return result; - } - - /** - * Produces JSON object for a route. - * - * @param mapper the JSON object mapper to use - * @param route the route with the data - * @return JSON object for the route - */ - private ObjectNode json(ObjectMapper mapper, RouteEntry route) { - ObjectNode result = mapper.createObjectNode(); - - result.put("prefix", route.prefix().toString()); - result.put("nextHop", route.nextHop().toString()); - - return result; - } -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/package-info.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/package-info.java deleted file mode 100644 index cb6781e3..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/cli/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -/** - * CLI handlers for routing commands. - */ -package org.onosproject.routing.cli; diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/Configuration.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/Configuration.java deleted file mode 100644 index c58bc1b9..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/Configuration.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2014-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.routing.config.impl; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.onlab.packet.MacAddress; -import org.onosproject.routing.config.BgpPeer; -import org.onosproject.routing.config.BgpSpeaker; -import org.onosproject.routing.config.LocalIpPrefixEntry; - -import java.util.Collections; -import java.util.List; - -/** - * Contains the configuration data for SDN-IP that has been read from a - * JSON-formatted configuration file. - */ -public class Configuration { - // We call the BGP routers in our SDN network the BGP speakers, and call - // the BGP routers outside our SDN network the BGP peers. - private List<BgpSpeaker> bgpSpeakers = Collections.emptyList(); - private List<BgpPeer> peers = Collections.emptyList(); - private MacAddress virtualGatewayMacAddress; - - // All IP prefixes from the configuration are local - private List<LocalIpPrefixEntry> localIp4PrefixEntries = - Collections.emptyList(); - private List<LocalIpPrefixEntry> localIp6PrefixEntries = - Collections.emptyList(); - - /** - * Default constructor. - */ - public Configuration() { - } - - /** - * Gets a list of bgpSpeakers in the system, represented by - * {@link BgpSpeaker} objects. - * - * @return the list of BGP speakers - */ - public List<BgpSpeaker> getBgpSpeakers() { - return Collections.unmodifiableList(bgpSpeakers); - } - - /** - * Sets a list of bgpSpeakers in the system. - * - * @param bgpSpeakers the list of BGP speakers - */ - @JsonProperty("bgpSpeakers") - public void setBgpSpeakers(List<BgpSpeaker> bgpSpeakers) { - this.bgpSpeakers = bgpSpeakers; - } - - /** - * Gets a list of BGP peers we are configured to peer with. Peers are - * represented by {@link BgpPeer} objects. - * - * @return the list of BGP peers - */ - public List<BgpPeer> getPeers() { - return Collections.unmodifiableList(peers); - } - - /** - * Sets a list of BGP peers we configured to peer with. - * - * @param peers the list of BGP peers - */ - @JsonProperty("bgpPeers") - public void setPeers(List<BgpPeer> peers) { - this.peers = peers; - } - - /** - * Gets the MAC address we configured for virtual gateway - * in SDN network. - * - * @return the MAC address of virtual gateway - */ - public MacAddress getVirtualGatewayMacAddress() { - return virtualGatewayMacAddress; - } - - /** - * Sets the MAC address for virtual gateway in SDN network. - * - * @param virtualGatewayMacAddress the MAC address of virtual gateway - */ - @JsonProperty("virtualGatewayMacAddress") - public void setVirtualGatewayMacAddress(MacAddress virtualGatewayMacAddress) { - this.virtualGatewayMacAddress = virtualGatewayMacAddress; - } - - /** - * Gets a list of local IPv4 prefix entries configured for local - * SDN network. - * <p> - * IP prefix entries are represented by {@link LocalIpPrefixEntry} - * objects. - * </p> - * - * @return the list of local IPv4 prefix entries - */ - public List<LocalIpPrefixEntry> getLocalIp4PrefixEntries() { - return Collections.unmodifiableList(localIp4PrefixEntries); - } - - /** - * Sets a list of IPv4 prefix entries configured for local SDN network. - * - * @param ip4PrefixEntries the list of Ipv4 prefix entries - */ - @JsonProperty("ip4LocalPrefixes") - public void setLocalIp4PrefixEntries(List<LocalIpPrefixEntry> ip4PrefixEntries) { - this.localIp4PrefixEntries = ip4PrefixEntries; - } - - /** - * Gets a list of IPv6 prefix entries configured for local SDN network. - * <p> - * IP prefix entries are represented by {@link LocalIpPrefixEntry} - * objects. - * </p> - * - * @return the list of IPv6 prefix entries - */ - public List<LocalIpPrefixEntry> getLocalIp6PrefixEntries() { - return Collections.unmodifiableList(localIp6PrefixEntries); - } - - /** - * Sets a list of IPv6 prefix entries configured for local SDN network. - * - * @param ip6PrefixEntries the list of Ipv6 prefix entries - */ - @JsonProperty("ip6LocalPrefixes") - public void setLocalIp6PrefixEntries(List<LocalIpPrefixEntry> ip6PrefixEntries) { - this.localIp6PrefixEntries = ip6PrefixEntries; - } - -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/RoutingConfigurationImpl.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/RoutingConfigurationImpl.java deleted file mode 100644 index 19c3f70b..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/RoutingConfigurationImpl.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2014-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.routing.config.impl; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; -import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; -import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; -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.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip6Address; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.incubator.net.intf.InterfaceService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.config.ConfigFactory; -import org.onosproject.net.config.NetworkConfigRegistry; -import org.onosproject.net.config.NetworkConfigService; -import org.onosproject.net.config.basics.SubjectFactories; -import org.onosproject.routing.config.BgpConfig; -import org.onosproject.routing.config.BgpPeer; -import org.onosproject.routing.config.BgpSpeaker; -import org.onosproject.routing.config.Interface; -import org.onosproject.routing.config.LocalIpPrefixEntry; -import org.onosproject.routing.config.RoutingConfigurationService; -import org.onosproject.routing.impl.Router; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -import static org.onosproject.routing.RouteEntry.createBinaryString; - -/** - * Implementation of RoutingConfigurationService which reads routing - * configuration from a file. - */ -@Component(immediate = true) -@Service -public class RoutingConfigurationImpl implements RoutingConfigurationService { - - private final Logger log = LoggerFactory.getLogger(getClass()); - - private static final String CONFIG_DIR = "../config"; - private static final String DEFAULT_CONFIG_FILE = "sdnip.json"; - private String configFileName = DEFAULT_CONFIG_FILE; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected NetworkConfigRegistry registry; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected NetworkConfigService configService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected InterfaceService interfaceService; - - private Map<String, BgpSpeaker> bgpSpeakers = new ConcurrentHashMap<>(); - private Map<IpAddress, BgpPeer> bgpPeers = new ConcurrentHashMap<>(); - private Set<IpAddress> gatewayIpAddresses = new HashSet<>(); - private Set<ConnectPoint> bgpPeerConnectPoints = new HashSet<>(); - - private InvertedRadixTree<LocalIpPrefixEntry> - localPrefixTable4 = new ConcurrentInvertedRadixTree<>( - new DefaultByteArrayNodeFactory()); - private InvertedRadixTree<LocalIpPrefixEntry> - localPrefixTable6 = new ConcurrentInvertedRadixTree<>( - new DefaultByteArrayNodeFactory()); - - private MacAddress virtualGatewayMacAddress; - - private ConfigFactory configFactory = - new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, BgpConfig.class, "bgp") { - @Override - public BgpConfig createConfig() { - return new BgpConfig(); - } - }; - - @Activate - public void activate() { - registry.registerConfigFactory(configFactory); - readConfiguration(); - log.info("Routing configuration service started"); - } - - @Deactivate - public void deactivate() { - registry.unregisterConfigFactory(configFactory); - log.info("Routing configuration service stopped"); - } - - /** - * Reads SDN-IP related information contained in the configuration file. - * - * @param configFilename the name of the configuration file for the SDN-IP - * application - */ - private void readConfiguration(String configFilename) { - File configFile = new File(CONFIG_DIR, configFilename); - ObjectMapper mapper = new ObjectMapper(); - - try { - log.info("Loading config: {}", configFile.getAbsolutePath()); - Configuration config = mapper.readValue(configFile, - Configuration.class); - for (BgpSpeaker speaker : config.getBgpSpeakers()) { - bgpSpeakers.put(speaker.name(), speaker); - } - for (BgpPeer peer : config.getPeers()) { - bgpPeers.put(peer.ipAddress(), peer); - bgpPeerConnectPoints.add(peer.connectPoint()); - } - - for (LocalIpPrefixEntry entry : config.getLocalIp4PrefixEntries()) { - localPrefixTable4.put(createBinaryString(entry.ipPrefix()), - entry); - gatewayIpAddresses.add(entry.getGatewayIpAddress()); - } - for (LocalIpPrefixEntry entry : config.getLocalIp6PrefixEntries()) { - localPrefixTable6.put(createBinaryString(entry.ipPrefix()), - entry); - gatewayIpAddresses.add(entry.getGatewayIpAddress()); - } - - virtualGatewayMacAddress = config.getVirtualGatewayMacAddress(); - - } catch (FileNotFoundException e) { - log.warn("Configuration file not found: {}", configFileName); - } catch (IOException e) { - log.error("Error loading configuration", e); - } - } - - /** - * Instructs the configuration reader to read the configuration from the - * file. - */ - public void readConfiguration() { - readConfiguration(configFileName); - } - - @Override - public Map<String, BgpSpeaker> getBgpSpeakers() { - return Collections.unmodifiableMap(bgpSpeakers); - } - - @Override - public Map<IpAddress, BgpPeer> getBgpPeers() { - return Collections.unmodifiableMap(bgpPeers); - } - - @Override - public Set<Interface> getInterfaces() { - return Collections.emptySet(); - } - - @Override - public Set<ConnectPoint> getBgpPeerConnectPoints() { - // TODO perhaps cache this result in future - ApplicationId routerAppId = coreService.getAppId(Router.ROUTER_APP_ID); - if (routerAppId == null) { - return Collections.emptySet(); - } - - BgpConfig bgpConfig = configService.getConfig(routerAppId, BgpConfig.class); - if (bgpConfig == null) { - return Collections.emptySet(); - } else { - return bgpConfig.bgpSpeakers().stream() - .flatMap(speaker -> speaker.peers().stream()) - .map(peer -> interfaceService.getMatchingInterface(peer)) - .filter(intf -> intf != null) - .map(intf -> intf.connectPoint()) - .collect(Collectors.toSet()); - } - } - - @Override - public Interface getInterface(ConnectPoint connectPoint) { - return null; - } - - @Override - public Interface getInterface(IpAddress ip) { - return null; - } - - @Override - public Interface getMatchingInterface(IpAddress ipAddress) { - return null; - } - - @Override - public boolean isIpAddressLocal(IpAddress ipAddress) { - if (ipAddress.isIp4()) { - return localPrefixTable4.getValuesForKeysPrefixing( - createBinaryString( - IpPrefix.valueOf(ipAddress, Ip4Address.BIT_LENGTH))) - .iterator().hasNext(); - } else { - return localPrefixTable6.getValuesForKeysPrefixing( - createBinaryString( - IpPrefix.valueOf(ipAddress, Ip6Address.BIT_LENGTH))) - .iterator().hasNext(); - } - } - - @Override - public boolean isIpPrefixLocal(IpPrefix ipPrefix) { - return (localPrefixTable4.getValueForExactKey( - createBinaryString(ipPrefix)) != null || - localPrefixTable6.getValueForExactKey( - createBinaryString(ipPrefix)) != null); - } - - @Override - public boolean isVirtualGatewayIpAddress(IpAddress ipAddress) { - return gatewayIpAddresses.contains(ipAddress); - } - - @Override - public MacAddress getVirtualGatewayMacAddress() { - return virtualGatewayMacAddress; - } - -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/package-info.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/package-info.java deleted file mode 100644 index 83c4a86d..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/config/impl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -/** - * Implementation of routing configuration APIs. - */ -package org.onosproject.routing.config.impl; diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java deleted file mode 100644 index 75d789ab..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright 2014-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.routing.impl; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimaps; -import com.google.common.collect.SetMultimap; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.googlecode.concurrenttrees.common.KeyValuePair; -import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; -import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; -import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; -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.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip6Address; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onosproject.core.CoreService; -import org.onosproject.incubator.net.intf.InterfaceService; -import org.onosproject.net.Host; -import org.onosproject.net.host.HostEvent; -import org.onosproject.net.host.HostListener; -import org.onosproject.net.host.HostService; -import org.onosproject.routing.BgpService; -import org.onosproject.routing.FibEntry; -import org.onosproject.routing.FibListener; -import org.onosproject.routing.FibUpdate; -import org.onosproject.routing.RouteEntry; -import org.onosproject.routing.RouteListener; -import org.onosproject.routing.RouteUpdate; -import org.onosproject.routing.RoutingService; -import org.onosproject.routing.config.RoutingConfigurationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.onosproject.routing.RouteEntry.createBinaryString; - -/** - * This class processes route updates and maintains a Routing Information Base - * (RIB). After route updates have been processed and next hops have been - * resolved, FIB updates are sent to any listening FIB components. - */ -@Component(immediate = true) -@Service -public class Router implements RoutingService { - - private static final Logger log = LoggerFactory.getLogger(Router.class); - - // Route entries are stored in a radix tree. - // The key in this tree is the binary string of prefix of the route. - private InvertedRadixTree<RouteEntry> ribTable4; - private InvertedRadixTree<RouteEntry> ribTable6; - - // Stores all incoming route updates in a queue. - private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue = - new LinkedBlockingQueue<>(); - - // Next-hop IP address to route entry mapping for next hops pending MAC - // resolution - private SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp; - - // The IPv4 address to MAC address mapping - private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>(); - - private FibListener fibComponent; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected HostService hostService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected BgpService bgpService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected InterfaceService interfaceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected RoutingConfigurationService routingConfigurationService; - - private ExecutorService bgpUpdatesExecutor; - private final HostListener hostListener = new InternalHostListener(); - - @Activate - public void activate() { - ribTable4 = new ConcurrentInvertedRadixTree<>( - new DefaultByteArrayNodeFactory()); - ribTable6 = new ConcurrentInvertedRadixTree<>( - new DefaultByteArrayNodeFactory()); - - routesWaitingOnArp = Multimaps.synchronizedSetMultimap( - HashMultimap.<IpAddress, RouteEntry>create()); - - coreService.registerApplication(ROUTER_APP_ID); - - bgpUpdatesExecutor = Executors.newSingleThreadExecutor( - new ThreadFactoryBuilder() - .setNameFormat("sdnip-bgp-updates-%d").build()); - } - - @Deactivate - public void deactivate() { - log.debug("Stopped"); - } - - @Override - public void addFibListener(FibListener fibListener) { - this.fibComponent = checkNotNull(fibListener); - } - - @Override - public void start() { - this.hostService.addListener(hostListener); - - bgpService.start(new InternalRouteListener()); - - bgpUpdatesExecutor.execute(this::doUpdatesThread); - } - - @Override - public void stop() { - bgpService.stop(); - - this.hostService.removeListener(hostListener); - - // Stop the thread(s) - bgpUpdatesExecutor.shutdownNow(); - - synchronized (this) { - // Cleanup all local state - ribTable4 = new ConcurrentInvertedRadixTree<>( - new DefaultByteArrayNodeFactory()); - ribTable6 = new ConcurrentInvertedRadixTree<>( - new DefaultByteArrayNodeFactory()); - routeUpdatesQueue.clear(); - routesWaitingOnArp.clear(); - ip2Mac.clear(); - } - } - - /** - * Entry point for route updates. - * - * @param routeUpdates collection of route updates to process - */ - private void update(Collection<RouteUpdate> routeUpdates) { - try { - routeUpdatesQueue.put(routeUpdates); - } catch (InterruptedException e) { - log.error("Interrupted while putting on routeUpdatesQueue", e); - Thread.currentThread().interrupt(); - } - } - - /** - * Thread for handling route updates. - */ - private void doUpdatesThread() { - boolean interrupted = false; - try { - while (!interrupted) { - try { - Collection<RouteUpdate> routeUpdates = - routeUpdatesQueue.take(); - processRouteUpdates(routeUpdates); - } catch (InterruptedException e) { - log.error("Interrupted while taking from updates queue", e); - interrupted = true; - } catch (Exception e) { - log.error("exception", e); - } - } - } finally { - if (interrupted) { - Thread.currentThread().interrupt(); - } - } - } - - /** - * Gets all IPv4 routes from the RIB. - * - * @return all IPv4 routes from the RIB - */ - @Override - public Collection<RouteEntry> getRoutes4() { - Iterator<KeyValuePair<RouteEntry>> it = - ribTable4.getKeyValuePairsForKeysStartingWith("").iterator(); - - List<RouteEntry> routes = new LinkedList<>(); - - while (it.hasNext()) { - KeyValuePair<RouteEntry> entry = it.next(); - routes.add(entry.getValue()); - } - - return routes; - } - - /** - * Gets all IPv6 routes from the RIB. - * - * @return all IPv6 routes from the RIB - */ - @Override - public Collection<RouteEntry> getRoutes6() { - Iterator<KeyValuePair<RouteEntry>> it = - ribTable6.getKeyValuePairsForKeysStartingWith("").iterator(); - - List<RouteEntry> routes = new LinkedList<>(); - - while (it.hasNext()) { - KeyValuePair<RouteEntry> entry = it.next(); - routes.add(entry.getValue()); - } - - return routes; - } - - /** - * Finds a route in the RIB for a prefix. The prefix can be either IPv4 or - * IPv6. - * - * @param prefix the prefix to use - * @return the route if found, otherwise null - */ - RouteEntry findRibRoute(IpPrefix prefix) { - String binaryString = createBinaryString(prefix); - if (prefix.isIp4()) { - // IPv4 - return ribTable4.getValueForExactKey(binaryString); - } - // IPv6 - return ribTable6.getValueForExactKey(binaryString); - } - - /** - * Adds a route to the RIB. The route can be either IPv4 or IPv6. - * - * @param routeEntry the route entry to use - */ - void addRibRoute(RouteEntry routeEntry) { - if (routeEntry.isIp4()) { - // IPv4 - ribTable4.put(createBinaryString(routeEntry.prefix()), routeEntry); - } else { - // IPv6 - ribTable6.put(createBinaryString(routeEntry.prefix()), routeEntry); - } - } - - /** - * Removes a route for a prefix from the RIB. The prefix can be either IPv4 - * or IPv6. - * - * @param prefix the prefix to use - * @return true if the route was found and removed, otherwise false - */ - boolean removeRibRoute(IpPrefix prefix) { - if (prefix.isIp4()) { - // IPv4 - return ribTable4.remove(createBinaryString(prefix)); - } - // IPv6 - return ribTable6.remove(createBinaryString(prefix)); - } - - /** - * Processes route updates. - * - * @param routeUpdates the route updates to process - */ - void processRouteUpdates(Collection<RouteUpdate> routeUpdates) { - synchronized (this) { - Collection<IpPrefix> withdrawPrefixes = new LinkedList<>(); - Collection<FibUpdate> fibUpdates = new LinkedList<>(); - Collection<FibUpdate> fibWithdraws = new LinkedList<>(); - - for (RouteUpdate update : routeUpdates) { - switch (update.type()) { - case UPDATE: - - FibEntry fib = processRouteAdd(update.routeEntry(), - withdrawPrefixes); - if (fib != null) { - fibUpdates.add(new FibUpdate(FibUpdate.Type.UPDATE, fib)); - } - - break; - case DELETE: - processRouteDelete(update.routeEntry(), withdrawPrefixes); - - break; - default: - log.error("Unknown update Type: {}", update.type()); - break; - } - } - - withdrawPrefixes.forEach(p -> fibWithdraws.add(new FibUpdate( - FibUpdate.Type.DELETE, new FibEntry(p, null, null)))); - - if (!fibUpdates.isEmpty() || !fibWithdraws.isEmpty()) { - fibComponent.update(fibUpdates, fibWithdraws); - } - } - } - - /** - * Processes adding a route entry. - * <p> - * The route entry is added to the radix tree. If there was an existing - * next hop for this prefix, but the next hop was different, then the - * old route entry is deleted. - * </p> - * <p> - * NOTE: Currently, we don't handle routes if the next hop is within the - * SDN domain. - * </p> - * - * @param routeEntry the route entry to add - * @param withdrawPrefixes the collection of accumulated prefixes whose - * intents will be withdrawn - * @return the corresponding FIB entry change, or null - */ - private FibEntry processRouteAdd(RouteEntry routeEntry, - Collection<IpPrefix> withdrawPrefixes) { - log.debug("Processing route add: {}", routeEntry); - - // Find the old next-hop if we are updating an old route entry - IpAddress oldNextHop = null; - RouteEntry oldRouteEntry = findRibRoute(routeEntry.prefix()); - if (oldRouteEntry != null) { - oldNextHop = oldRouteEntry.nextHop(); - } - - // Add the new route to the RIB - addRibRoute(routeEntry); - - if (oldNextHop != null) { - if (oldNextHop.equals(routeEntry.nextHop())) { - return null; // No change - } - // - // Update an existing nexthop for the prefix. - // We need to remove the old flows for this prefix from the - // switches before the new flows are added. - // - withdrawPrefixes.add(routeEntry.prefix()); - } - - if (routingConfigurationService.isIpPrefixLocal(routeEntry.prefix())) { - // Route originated by local SDN domain - // We don't handle these here, reactive routing APP will handle - // these - log.debug("Own route {} to {}", - routeEntry.prefix(), routeEntry.nextHop()); - return null; - } - - // - // Find the MAC address of next hop router for this route entry. - // If the MAC address can not be found in ARP cache, then this prefix - // will be put in routesWaitingOnArp queue. Otherwise, generate - // a new route intent. - // - - // Monitor the IP address for updates of the MAC address - hostService.startMonitoringIp(routeEntry.nextHop()); - - // Check if we know the MAC address of the next hop - MacAddress nextHopMacAddress = ip2Mac.get(routeEntry.nextHop()); - if (nextHopMacAddress == null) { - Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop()); - if (!hosts.isEmpty()) { - nextHopMacAddress = hosts.iterator().next().mac(); - } - if (nextHopMacAddress != null) { - ip2Mac.put(routeEntry.nextHop(), nextHopMacAddress); - } - } - if (nextHopMacAddress == null) { - routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry); - return null; - } - return new FibEntry(routeEntry.prefix(), routeEntry.nextHop(), - nextHopMacAddress); - } - - /** - * Processes the deletion of a route entry. - * <p> - * The prefix for the routing entry is removed from radix tree. - * If the operation is successful, the prefix is added to the collection - * of prefixes whose intents that will be withdrawn. - * </p> - * - * @param routeEntry the route entry to delete - * @param withdrawPrefixes the collection of accumulated prefixes whose - * intents will be withdrawn - */ - private void processRouteDelete(RouteEntry routeEntry, - Collection<IpPrefix> withdrawPrefixes) { - log.debug("Processing route delete: {}", routeEntry); - boolean isRemoved = removeRibRoute(routeEntry.prefix()); - - if (isRemoved) { - // - // Only withdraw intents if an entry was actually removed from the - // tree. If no entry was removed, the <prefix, nexthop> wasn't - // there so it's probably already been removed and we don't - // need to do anything. - // - withdrawPrefixes.add(routeEntry.prefix()); - } - - routesWaitingOnArp.remove(routeEntry.nextHop(), routeEntry); - } - - /** - * Signals the Router that the MAC to IP mapping has potentially been - * updated. This has the effect of updating the MAC address for any - * installed prefixes if it has changed, as well as installing any pending - * prefixes that were waiting for MAC resolution. - * - * @param ipAddress the IP address that an event was received for - * @param macAddress the most recently known MAC address for the IP address - */ - private void updateMac(IpAddress ipAddress, MacAddress macAddress) { - log.debug("Received updated MAC info: {} => {}", ipAddress, - macAddress); - - // - // We synchronize on "this" to prevent changes to the Radix tree - // while we're pushing intents. If the tree changes, the - // tree and the intents could get out of sync. - // - synchronized (this) { - Collection<FibUpdate> submitFibEntries = new LinkedList<>(); - - Set<RouteEntry> routesToPush = - routesWaitingOnArp.removeAll(ipAddress); - - for (RouteEntry routeEntry : routesToPush) { - // These will always be adds - RouteEntry foundRouteEntry = findRibRoute(routeEntry.prefix()); - if (foundRouteEntry != null && - foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { - // We only push FIB updates if the prefix is still in the - // radix tree and the next hop is the same as our entry. - // The prefix could have been removed while we were waiting - // for the ARP, or the next hop could have changed. - submitFibEntries.add(new FibUpdate(FibUpdate.Type.UPDATE, - new FibEntry(routeEntry.prefix(), - ipAddress, macAddress))); - } else { - log.debug("{} has been revoked before the MAC was resolved", - routeEntry); - } - } - - if (!submitFibEntries.isEmpty()) { - fibComponent.update(submitFibEntries, Collections.emptyList()); - } - - ip2Mac.put(ipAddress, macAddress); - } - } - - /** - * Listener for host events. - */ - class InternalHostListener implements HostListener { - @Override - public void event(HostEvent event) { - log.debug("Received HostEvent {}", event); - - Host host = event.subject(); - switch (event.type()) { - case HOST_ADDED: - // FALLTHROUGH - case HOST_UPDATED: - for (IpAddress ipAddress : host.ipAddresses()) { - updateMac(ipAddress, host.mac()); - } - break; - case HOST_REMOVED: - for (IpAddress ipAddress : host.ipAddresses()) { - ip2Mac.remove(ipAddress); - } - break; - default: - break; - } - } - } - - /** - * Listener for route events. - */ - private class InternalRouteListener implements RouteListener { - @Override - public void update(Collection<RouteUpdate> routeUpdates) { - Router.this.update(routeUpdates); - } - } - - @Override - public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) { - RouteEntry routeEntry = null; - Iterable<RouteEntry> routeEntries; - - if (ipAddress.isIp4()) { - routeEntries = ribTable4.getValuesForKeysPrefixing( - createBinaryString( - IpPrefix.valueOf(ipAddress, Ip4Address.BIT_LENGTH))); - } else { - routeEntries = ribTable6.getValuesForKeysPrefixing( - createBinaryString( - IpPrefix.valueOf(ipAddress, Ip6Address.BIT_LENGTH))); - } - if (routeEntries == null) { - return null; - } - Iterator<RouteEntry> it = routeEntries.iterator(); - while (it.hasNext()) { - routeEntry = it.next(); - } - return routeEntry; - } - -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/StaticRouter.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/StaticRouter.java deleted file mode 100644 index 3c868202..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/StaticRouter.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.routing.impl; - -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.IpAddress; -import org.onosproject.routing.FibListener; -import org.onosproject.routing.RouteEntry; -import org.onosproject.routing.RoutingService; -import org.onosproject.routing.StaticRoutingService; - -import java.util.Collection; - -/** - * Static router maintains handle to FIB listener. - * - * TODO: implement getRoutes methods - */ -@Component(immediate = true, enabled = false) -@Service -public class StaticRouter implements RoutingService, StaticRoutingService { - private FibListener fibListener; - - @Override - public void start() { - - } - - @Override - public void addFibListener(FibListener fibListener) { - this.fibListener = fibListener; - } - - @Override - public void stop() { - - } - - @Override - public Collection<RouteEntry> getRoutes4() { - return null; - } - - @Override - public Collection<RouteEntry> getRoutes6() { - return null; - } - - @Override - public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) { - return null; - } - - @Override - public FibListener getFibListener() { - return fibListener; - } - -} diff --git a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/package-info.java b/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/package-info.java deleted file mode 100644 index bb64bf67..00000000 --- a/framework/src/onos/apps/routing/src/main/java/org/onosproject/routing/impl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -/** - * Implementation of routing functionality. - */ -package org.onosproject.routing.impl; diff --git a/framework/src/onos/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml deleted file mode 100644 index 866e1c4a..00000000 --- a/framework/src/onos/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ /dev/null @@ -1,38 +0,0 @@ -<!-- - ~ 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. - --> -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> - - <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> - <command> - <action class="org.onosproject.routing.cli.BgpNeighborsListCommand"/> - </command> - <command> - <action class="org.onosproject.routing.cli.BgpRoutesListCommand"/> - </command> - <command> - <action class="org.onosproject.routing.cli.RoutesListCommand"/> - </command> - <command> - <action class="org.onosproject.routing.cli.AddRouteCommand"/> - </command> - <command> - <action class="org.onosproject.routing.cli.RemoveRouteCommand"/> - </command> - <command> - <action class="org.onosproject.routing.cli.BgpSpeakersListCommand"/> - </command> - </command-bundle> -</blueprint> diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java deleted file mode 100644 index 9213e4e0..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/AsPathTest.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.hamcrest.Matchers; -import org.junit.Test; - -import java.util.ArrayList; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; - -/** - * Unit tests for the BgpRouteEntry.AsPath class. - */ -public class AsPathTest { - /** - * Generates Path Segments. - * - * @return the generated Path Segments - */ - private ArrayList<BgpRouteEntry.PathSegment> generatePathSegments() { - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType; - ArrayList<Long> segmentAsNumbers; - BgpRouteEntry.PathSegment pathSegment; - - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(1L); - segmentAsNumbers.add(2L); - segmentAsNumbers.add(3L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - // - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(4L); - segmentAsNumbers.add(5L); - segmentAsNumbers.add(6L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - // - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(7L); - segmentAsNumbers.add(8L); - segmentAsNumbers.add(9L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - // - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(10L); - segmentAsNumbers.add(11L); - segmentAsNumbers.add(12L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - - return pathSegments; - } - - /** - * Generates an AS Path. - * - * @return a generated AS Path - */ - private BgpRouteEntry.AsPath generateAsPath() { - ArrayList<BgpRouteEntry.PathSegment> pathSegments = - generatePathSegments(); - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - - return asPath; - } - - /** - * Tests valid class constructor. - */ - @Test - public void testConstructor() { - BgpRouteEntry.AsPath asPath = generateAsPath(); - - String expectedString = - "AsPath{pathSegments=[" + - "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + - "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " + - "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " + - "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}"; - assertThat(asPath.toString(), is(expectedString)); - } - - /** - * Tests invalid class constructor for null Path Segments. - */ - @Test(expected = NullPointerException.class) - public void testInvalidConstructorNullPathSegments() { - ArrayList<BgpRouteEntry.PathSegment> pathSegments = null; - new BgpRouteEntry.AsPath(pathSegments); - } - - /** - * Tests getting the fields of an AS Path. - */ - @Test - public void testGetFields() { - // Create the fields to compare against - ArrayList<BgpRouteEntry.PathSegment> pathSegments = - generatePathSegments(); - - // Generate the entry to test - BgpRouteEntry.AsPath asPath = generateAsPath(); - - assertThat(asPath.getPathSegments(), is(pathSegments)); - } - - /** - * Tests getting the AS Path Length. - */ - @Test - public void testGetAsPathLength() { - // - // NOTE: - // - AS_CONFED_SEQUENCE and AS_CONFED_SET are excluded - // - AS_SET counts as a single hop - // - BgpRouteEntry.AsPath asPath = generateAsPath(); - assertThat(asPath.getAsPathLength(), is(4)); - - // Create an empty AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - asPath = new BgpRouteEntry.AsPath(pathSegments); - assertThat(asPath.getAsPathLength(), is(0)); - } - - /** - * Tests equality of {@link BgpRouteEntry.AsPath}. - */ - @Test - public void testEquality() { - BgpRouteEntry.AsPath asPath1 = generateAsPath(); - BgpRouteEntry.AsPath asPath2 = generateAsPath(); - - assertThat(asPath1, is(asPath2)); - } - - /** - * Tests non-equality of {@link BgpRouteEntry.AsPath}. - */ - @Test - public void testNonEquality() { - BgpRouteEntry.AsPath asPath1 = generateAsPath(); - - // Setup AS Path 2 - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType; - ArrayList<Long> segmentAsNumbers; - BgpRouteEntry.PathSegment pathSegment; - - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(1L); - segmentAsNumbers.add(2L); - segmentAsNumbers.add(3L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - // - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(4L); - segmentAsNumbers.add(5L); - segmentAsNumbers.add(6L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - // - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(7L); - segmentAsNumbers.add(8L); - segmentAsNumbers.add(9L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - // - pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET; - segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(10L); - segmentAsNumbers.add(111L); // Different - segmentAsNumbers.add(12L); - pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - pathSegments.add(pathSegment); - // - BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments); - - assertThat(asPath1, Matchers.is(not(asPath2))); - } - - /** - * Tests object string representation. - */ - @Test - public void testToString() { - BgpRouteEntry.AsPath asPath = generateAsPath(); - - String expectedString = - "AsPath{pathSegments=[" + - "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + - "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " + - "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " + - "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}"; - assertThat(asPath.toString(), is(expectedString)); - } -} diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java deleted file mode 100644 index 446056e9..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.easymock.EasyMock; -import org.hamcrest.Matchers; -import org.junit.Before; -import org.junit.Test; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; - -import java.util.ArrayList; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; - -/** - * Unit tests for the BgpRouteEntry class. - */ -public class BgpRouteEntryTest { - private BgpSession bgpSession; - private static final Ip4Address BGP_SESSION_BGP_ID = - Ip4Address.valueOf("10.0.0.1"); - private static final Ip4Address BGP_SESSION_IP_ADDRESS = - Ip4Address.valueOf("20.0.0.1"); - - private BgpSession bgpSession2; - private static final Ip4Address BGP_SESSION_BGP_ID2 = - Ip4Address.valueOf("10.0.0.2"); - private static final Ip4Address BGP_SESSION_IP_ADDRESS2 = - Ip4Address.valueOf("20.0.0.1"); - - private BgpSession bgpSession3; - private static final Ip4Address BGP_SESSION_BGP_ID3 = - Ip4Address.valueOf("10.0.0.1"); - private static final Ip4Address BGP_SESSION_IP_ADDRESS3 = - Ip4Address.valueOf("20.0.0.2"); - - private final BgpSessionInfo localInfo = new BgpSessionInfo(); - private final BgpSessionInfo remoteInfo = new BgpSessionInfo(); - - private final BgpSessionInfo localInfo2 = new BgpSessionInfo(); - private final BgpSessionInfo remoteInfo2 = new BgpSessionInfo(); - - private final BgpSessionInfo localInfo3 = new BgpSessionInfo(); - private final BgpSessionInfo remoteInfo3 = new BgpSessionInfo(); - - @Before - public void setUp() throws Exception { - // Mock objects for testing - bgpSession = EasyMock.createMock(BgpSession.class); - bgpSession2 = EasyMock.createMock(BgpSession.class); - bgpSession3 = EasyMock.createMock(BgpSession.class); - - // Setup the BGP Sessions - remoteInfo.setIp4Address(BGP_SESSION_IP_ADDRESS); - remoteInfo2.setIp4Address(BGP_SESSION_IP_ADDRESS2); - remoteInfo3.setIp4Address(BGP_SESSION_IP_ADDRESS3); - remoteInfo.setBgpId(BGP_SESSION_BGP_ID); - remoteInfo2.setBgpId(BGP_SESSION_BGP_ID2); - remoteInfo3.setBgpId(BGP_SESSION_BGP_ID3); - - EasyMock.expect(bgpSession.localInfo()).andReturn(localInfo).anyTimes(); - EasyMock.expect(bgpSession.remoteInfo()).andReturn(remoteInfo).anyTimes(); - EasyMock.expect(bgpSession2.localInfo()).andReturn(localInfo2).anyTimes(); - EasyMock.expect(bgpSession2.remoteInfo()).andReturn(remoteInfo2).anyTimes(); - EasyMock.expect(bgpSession3.localInfo()).andReturn(localInfo3).anyTimes(); - EasyMock.expect(bgpSession3.remoteInfo()).andReturn(remoteInfo3).anyTimes(); - - EasyMock.replay(bgpSession); - EasyMock.replay(bgpSession2); - EasyMock.replay(bgpSession3); - } - - /** - * Generates a BGP Route Entry. - * - * @return a generated BGP Route Entry - */ - private BgpRouteEntry generateBgpRouteEntry() { - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - // Setup the AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); - segmentAsNumbers1.add(1L); - segmentAsNumbers1.add(2L); - segmentAsNumbers1.add(3L); - BgpRouteEntry.PathSegment pathSegment1 = - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); - pathSegments.add(pathSegment1); - // - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); - segmentAsNumbers2.add(4L); - segmentAsNumbers2.add(5L); - segmentAsNumbers2.add(6L); - BgpRouteEntry.PathSegment pathSegment2 = - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); - pathSegments.add(pathSegment2); - // - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - // - long localPref = 100; - long multiExitDisc = 20; - - BgpRouteEntry bgpRouteEntry = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry.setMultiExitDisc(multiExitDisc); - - return bgpRouteEntry; - } - - /** - * Tests valid class constructor. - */ - @Test - public void testConstructor() { - BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry(); - - String expectedString = - "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " + - "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" + - "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + - "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " + - "localPref=100, multiExitDisc=20}"; - assertThat(bgpRouteEntry.toString(), is(expectedString)); - } - - /** - * Tests invalid class constructor for null BGP Session. - */ - @Test(expected = NullPointerException.class) - public void testInvalidConstructorNullBgpSession() { - BgpSession bgpSessionNull = null; - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - // Setup the AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - // - long localPref = 100; - - new BgpRouteEntry(bgpSessionNull, prefix, nextHop, origin, asPath, - localPref); - } - - /** - * Tests invalid class constructor for null AS Path. - */ - @Test(expected = NullPointerException.class) - public void testInvalidConstructorNullAsPath() { - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - BgpRouteEntry.AsPath asPath = null; - long localPref = 100; - - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - } - - /** - * Tests getting the fields of a BGP route entry. - */ - @Test - public void testGetFields() { - // Create the fields to compare against - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - // Setup the AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); - segmentAsNumbers1.add(1L); - segmentAsNumbers1.add(2L); - segmentAsNumbers1.add(3L); - BgpRouteEntry.PathSegment pathSegment1 = - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); - pathSegments.add(pathSegment1); - // - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); - segmentAsNumbers2.add(4L); - segmentAsNumbers2.add(5L); - segmentAsNumbers2.add(6L); - BgpRouteEntry.PathSegment pathSegment2 = - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); - pathSegments.add(pathSegment2); - // - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - // - long localPref = 100; - long multiExitDisc = 20; - - // Generate the entry to test - BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry(); - - assertThat(bgpRouteEntry.prefix(), is(prefix)); - assertThat(bgpRouteEntry.nextHop(), is(nextHop)); - assertThat(bgpRouteEntry.getBgpSession(), is(bgpSession)); - assertThat(bgpRouteEntry.getOrigin(), is(origin)); - assertThat(bgpRouteEntry.getAsPath(), is(asPath)); - assertThat(bgpRouteEntry.getLocalPref(), is(localPref)); - assertThat(bgpRouteEntry.getMultiExitDisc(), is(multiExitDisc)); - } - - /** - * Tests whether a BGP route entry is a local route. - */ - @Test - public void testIsLocalRoute() { - // - // Test non-local route - // - BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry(); - assertThat(bgpRouteEntry.isLocalRoute(), is(false)); - - // - // Test local route with AS Path that begins with AS_SET - // - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - // Setup the AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SET; - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); - segmentAsNumbers1.add(1L); - segmentAsNumbers1.add(2L); - segmentAsNumbers1.add(3L); - BgpRouteEntry.PathSegment pathSegment1 = - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); - pathSegments.add(pathSegment1); - // - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); - segmentAsNumbers2.add(4L); - segmentAsNumbers2.add(5L); - segmentAsNumbers2.add(6L); - BgpRouteEntry.PathSegment pathSegment2 = - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); - pathSegments.add(pathSegment2); - // - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - // - long localPref = 100; - long multiExitDisc = 20; - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry.setMultiExitDisc(multiExitDisc); - assertThat(bgpRouteEntry.isLocalRoute(), is(true)); - - // - // Test local route with empty AS Path - // - pathSegments = new ArrayList<>(); - asPath = new BgpRouteEntry.AsPath(pathSegments); - bgpRouteEntry = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry.setMultiExitDisc(multiExitDisc); - assertThat(bgpRouteEntry.isLocalRoute(), is(true)); - } - - /** - * Tests getting the BGP Neighbor AS number for a route. - */ - @Test - public void testGetNeighborAs() { - // - // Get neighbor AS for non-local route - // - BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry(); - assertThat(bgpRouteEntry.getNeighborAs(), is(1L)); - - // - // Get neighbor AS for a local route - // - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - // Setup the AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - // - long localPref = 100; - long multiExitDisc = 20; - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry.setMultiExitDisc(multiExitDisc); - assertThat(bgpRouteEntry.getNeighborAs(), is(BgpConstants.BGP_AS_0)); - } - - /** - * Tests whether a BGP route entry has AS Path loop. - */ - @Test - public void testHasAsPathLoop() { - BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry(); - - // Test for loops: test each AS number in the interval [1, 6] - for (int i = 1; i <= 6; i++) { - assertThat(bgpRouteEntry.hasAsPathLoop(i), is(true)); - } - - // Test for non-loops - assertThat(bgpRouteEntry.hasAsPathLoop(500), is(false)); - } - - /** - * Tests the BGP Decision Process comparison of BGP routes. - */ - @Test - public void testBgpDecisionProcessComparison() { - BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry(); - BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry(); - - // - // Compare two routes that are same - // - assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true)); - assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true)); - - // - // Compare two routes with different LOCAL_PREF - // - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - // Setup the AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); - segmentAsNumbers1.add(1L); - segmentAsNumbers1.add(2L); - segmentAsNumbers1.add(3L); - BgpRouteEntry.PathSegment pathSegment1 = - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); - pathSegments.add(pathSegment1); - // - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); - segmentAsNumbers2.add(4L); - segmentAsNumbers2.add(5L); - segmentAsNumbers2.add(6L); - BgpRouteEntry.PathSegment pathSegment2 = - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); - pathSegments.add(pathSegment2); - // - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - // - long localPref = 50; // Different - long multiExitDisc = 20; - bgpRouteEntry2 = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry2.setMultiExitDisc(multiExitDisc); - // - assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true)); - assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false)); - localPref = bgpRouteEntry1.getLocalPref(); // Restore - - // - // Compare two routes with different AS_PATH length - // - ArrayList<BgpRouteEntry.PathSegment> pathSegments2 = new ArrayList<>(); - pathSegments2.add(pathSegment1); - // Different AS Path - BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments2); - bgpRouteEntry2 = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath2, - localPref); - bgpRouteEntry2.setMultiExitDisc(multiExitDisc); - // - assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(false)); - assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true)); - - // - // Compare two routes with different ORIGIN - // - origin = BgpConstants.Update.Origin.EGP; // Different - bgpRouteEntry2 = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry2.setMultiExitDisc(multiExitDisc); - // - assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true)); - assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false)); - origin = bgpRouteEntry1.getOrigin(); // Restore - - // - // Compare two routes with different MULTI_EXIT_DISC - // - multiExitDisc = 10; // Different - bgpRouteEntry2 = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry2.setMultiExitDisc(multiExitDisc); - // - assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true)); - assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false)); - multiExitDisc = bgpRouteEntry1.getMultiExitDisc(); // Restore - - // - // Compare two routes with different BGP ID - // - bgpRouteEntry2 = - new BgpRouteEntry(bgpSession2, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry2.setMultiExitDisc(multiExitDisc); - // - assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true)); - assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false)); - - // - // Compare two routes with different BGP address - // - bgpRouteEntry2 = - new BgpRouteEntry(bgpSession3, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry2.setMultiExitDisc(multiExitDisc); - // - assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true)); - assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false)); - } - - /** - * Tests equality of {@link BgpRouteEntry}. - */ - @Test - public void testEquality() { - BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry(); - BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry(); - - assertThat(bgpRouteEntry1, is(bgpRouteEntry2)); - } - - /** - * Tests non-equality of {@link BgpRouteEntry}. - */ - @Test - public void testNonEquality() { - BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry(); - - // Setup BGP Route 2 - Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24"); - Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8"); - byte origin = BgpConstants.Update.Origin.IGP; - // Setup the AS Path - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); - segmentAsNumbers1.add(1L); - segmentAsNumbers1.add(2L); - segmentAsNumbers1.add(3L); - BgpRouteEntry.PathSegment pathSegment1 = - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); - pathSegments.add(pathSegment1); - // - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); - segmentAsNumbers2.add(4L); - segmentAsNumbers2.add(5L); - segmentAsNumbers2.add(6L); - BgpRouteEntry.PathSegment pathSegment2 = - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); - pathSegments.add(pathSegment2); - // - BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); - // - long localPref = 500; // Different - long multiExitDisc = 20; - BgpRouteEntry bgpRouteEntry2 = - new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath, - localPref); - bgpRouteEntry2.setMultiExitDisc(multiExitDisc); - - assertThat(bgpRouteEntry1, Matchers.is(not(bgpRouteEntry2))); - } - - /** - * Tests object string representation. - */ - @Test - public void testToString() { - BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry(); - - String expectedString = - "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " + - "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" + - "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " + - "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " + - "localPref=100, multiExitDisc=20}"; - assertThat(bgpRouteEntry.toString(), is(expectedString)); - } -} diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java deleted file mode 100644 index 3f5a6b8b..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java +++ /dev/null @@ -1,891 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import com.google.common.net.InetAddresses; -import org.hamcrest.Description; -import org.hamcrest.TypeSafeMatcher; -import org.jboss.netty.bootstrap.ClientBootstrap; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFactory; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.onlab.junit.TestUtils; -import org.onlab.junit.TestUtils.TestUtilsException; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onosproject.routing.RouteListener; -import org.onosproject.routing.RouteUpdate; -import org.osgi.service.component.ComponentContext; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Dictionary; -import java.util.LinkedList; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; - -/** - * Unit tests for the BgpSessionManager class. - */ -public class BgpSessionManagerTest { - private static final Ip4Address IP_LOOPBACK_ID = - Ip4Address.valueOf("127.0.0.1"); - private static final Ip4Address BGP_PEER1_ID = - Ip4Address.valueOf("10.0.0.1"); - private static final Ip4Address BGP_PEER2_ID = - Ip4Address.valueOf("10.0.0.2"); - private static final Ip4Address BGP_PEER3_ID = - Ip4Address.valueOf("10.0.0.3"); - private static final Ip4Address NEXT_HOP1_ROUTER = - Ip4Address.valueOf("10.20.30.41"); - private static final Ip4Address NEXT_HOP2_ROUTER = - Ip4Address.valueOf("10.20.30.42"); - private static final Ip4Address NEXT_HOP3_ROUTER = - Ip4Address.valueOf("10.20.30.43"); - - private static final long DEFAULT_LOCAL_PREF = 10; - private static final long BETTER_LOCAL_PREF = 20; - private static final long DEFAULT_MULTI_EXIT_DISC = 20; - private static final long BETTER_MULTI_EXIT_DISC = 30; - - BgpRouteEntry.AsPath asPathShort; - BgpRouteEntry.AsPath asPathLong; - - // Timeout waiting for a message to be received - private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s - - // The BGP Session Manager to test - private BgpSessionManager bgpSessionManager; - - // Remote Peer state - private final Collection<TestBgpPeer> peers = new LinkedList<>(); - TestBgpPeer peer1; - TestBgpPeer peer2; - TestBgpPeer peer3; - - // Local BGP per-peer session state - BgpSession bgpSession1; - BgpSession bgpSession2; - BgpSession bgpSession3; - - // The socket that the remote peers should connect to - private InetSocketAddress connectToSocket; - - private final DummyRouteListener dummyRouteListener = - new DummyRouteListener(); - - /** - * Dummy implementation for the RouteListener interface. - */ - private class DummyRouteListener implements RouteListener { - @Override - public void update(Collection<RouteUpdate> routeUpdate) { - // Nothing to do - } - } - - /** - * A class to capture the state for a BGP peer. - */ - private final class TestBgpPeer { - private final Ip4Address peerId; - private ClientBootstrap peerBootstrap; - private TestBgpPeerChannelHandler peerChannelHandler; - private TestBgpPeerFrameDecoder peerFrameDecoder = - new TestBgpPeerFrameDecoder(); - - /** - * Constructor. - * - * @param peerId the peer ID - */ - private TestBgpPeer(Ip4Address peerId) { - this.peerId = peerId; - peerChannelHandler = new TestBgpPeerChannelHandler(peerId); - } - - /** - * Starts up the BGP peer and connects it to the tested SDN-IP - * instance. - * - * @param connectToSocket the socket to connect to - */ - private void connect(InetSocketAddress connectToSocket) - throws InterruptedException { - // - // Setup the BGP Peer, i.e., the "remote" BGP router that will - // initiate the BGP connection, send BGP UPDATE messages, etc. - // - ChannelFactory channelFactory = - new NioClientSocketChannelFactory( - Executors.newCachedThreadPool(), - Executors.newCachedThreadPool()); - ChannelPipelineFactory pipelineFactory = () -> { - // Setup the transmitting pipeline - ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("TestBgpPeerFrameDecoder", - peerFrameDecoder); - pipeline.addLast("TestBgpPeerChannelHandler", - peerChannelHandler); - return pipeline; - }; - - peerBootstrap = new ClientBootstrap(channelFactory); - peerBootstrap.setOption("child.keepAlive", true); - peerBootstrap.setOption("child.tcpNoDelay", true); - peerBootstrap.setPipelineFactory(pipelineFactory); - peerBootstrap.connect(connectToSocket); - - boolean result; - // Wait until the OPEN message is received - result = peerFrameDecoder.receivedOpenMessageLatch.await( - MESSAGE_TIMEOUT_MS, - TimeUnit.MILLISECONDS); - assertThat(result, is(true)); - // Wait until the KEEPALIVE message is received - result = peerFrameDecoder.receivedKeepaliveMessageLatch.await( - MESSAGE_TIMEOUT_MS, - TimeUnit.MILLISECONDS); - assertThat(result, is(true)); - - for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) { - if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) { - bgpSession1 = bgpSession; - } - if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) { - bgpSession2 = bgpSession; - } - if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) { - bgpSession3 = bgpSession; - } - } - } - } - - /** - * Class that implements a matcher for BgpRouteEntry by considering - * the BGP peer the entry was received from. - */ - private static final class BgpRouteEntryAndPeerMatcher - extends TypeSafeMatcher<Collection<BgpRouteEntry>> { - private final BgpRouteEntry bgpRouteEntry; - - private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) { - this.bgpRouteEntry = bgpRouteEntry; - } - - @Override - public boolean matchesSafely(Collection<BgpRouteEntry> entries) { - for (BgpRouteEntry entry : entries) { - if (bgpRouteEntry.equals(entry) && - bgpRouteEntry.getBgpSession() == entry.getBgpSession()) { - return true; - } - } - return false; - } - - @Override - public void describeTo(Description description) { - description.appendText("BGP route entry lookup for entry \""). - appendText(bgpRouteEntry.toString()). - appendText("\""); - } - } - - /** - * A helper method used for testing whether a collection of - * BGP route entries contains an entry from a specific BGP peer. - * - * @param bgpRouteEntry the BGP route entry to test - * @return an instance of BgpRouteEntryAndPeerMatcher that implements - * the matching logic - */ - private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry( - BgpRouteEntry bgpRouteEntry) { - return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry); - } - - @SuppressWarnings("unchecked") - private Dictionary<String, String> - getDictionaryMock(ComponentContext componentContext) { - Dictionary<String, String> dictionary = createMock(Dictionary.class); - expect(dictionary.get("bgpPort")).andReturn("0"); - replay(dictionary); - expect(componentContext.getProperties()).andReturn(dictionary); - return dictionary; - } - - @Before - public void setUp() throws Exception { - peer1 = new TestBgpPeer(BGP_PEER1_ID); - peer2 = new TestBgpPeer(BGP_PEER2_ID); - peer3 = new TestBgpPeer(BGP_PEER3_ID); - peers.clear(); - peers.add(peer1); - peers.add(peer2); - peers.add(peer3); - - // - // Setup the BGP Session Manager to test, and start listening for BGP - // connections. - // - bgpSessionManager = new BgpSessionManager(); - // NOTE: We use port 0 to bind on any available port - ComponentContext componentContext = createMock(ComponentContext.class); - Dictionary<String, String> dictionary = getDictionaryMock(componentContext); - replay(componentContext); - bgpSessionManager.activate(componentContext); - bgpSessionManager.start(dummyRouteListener); - - // Get the port number the BGP Session Manager is listening on - Channel serverChannel = TestUtils.getField(bgpSessionManager, - "serverChannel"); - SocketAddress socketAddress = serverChannel.getLocalAddress(); - InetSocketAddress inetSocketAddress = - (InetSocketAddress) socketAddress; - InetAddress connectToAddress = InetAddresses.forString("127.0.0.1"); - connectToSocket = new InetSocketAddress(connectToAddress, - inetSocketAddress.getPort()); - - // - // Setup the AS Paths - // - ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); - byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); - segmentAsNumbers1.add(65010L); - segmentAsNumbers1.add(65020L); - segmentAsNumbers1.add(65030L); - BgpRouteEntry.PathSegment pathSegment1 = - new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); - pathSegments.add(pathSegment1); - asPathShort = new BgpRouteEntry.AsPath(new ArrayList<>(pathSegments)); - // - byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; - ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); - segmentAsNumbers2.add(65041L); - segmentAsNumbers2.add(65042L); - segmentAsNumbers2.add(65043L); - BgpRouteEntry.PathSegment pathSegment2 = - new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); - pathSegments.add(pathSegment2); - // - asPathLong = new BgpRouteEntry.AsPath(pathSegments); - } - - @After - public void tearDown() throws Exception { - bgpSessionManager.stop(); - bgpSessionManager = null; - } - - /** - * Gets BGP RIB-IN routes by waiting until they are received. - * <p> - * NOTE: We keep checking once every 10ms the number of received routes, - * up to 5 seconds. - * </p> - * - * @param bgpSession the BGP session that is expected to receive the - * routes - * @param expectedRoutes the expected number of routes - * @return the BGP RIB-IN routes as received within the expected - * time interval - */ - private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession, - long expectedRoutes) - throws InterruptedException { - Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4(); - - final int maxChecks = 500; // Max wait of 5 seconds - for (int i = 0; i < maxChecks; i++) { - if (bgpRibIn.size() == expectedRoutes) { - break; - } - Thread.sleep(10); - bgpRibIn = bgpSession.getBgpRibIn4(); - } - - return bgpRibIn; - } - - /** - * Gets BGP merged routes by waiting until they are received. - * <p> - * NOTE: We keep checking once every 10ms the number of received routes, - * up to 5 seconds. - * </p> - * - * @param expectedRoutes the expected number of routes - * @return the BGP Session Manager routes as received within the expected - * time interval - */ - private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes) - throws InterruptedException { - Collection<BgpRouteEntry> bgpRoutes = - bgpSessionManager.getBgpRoutes4(); - - final int maxChecks = 500; // Max wait of 5 seconds - for (int i = 0; i < maxChecks; i++) { - if (bgpRoutes.size() == expectedRoutes) { - break; - } - Thread.sleep(10); - bgpRoutes = bgpSessionManager.getBgpRoutes4(); - } - - return bgpRoutes; - } - - /** - * Gets a merged BGP route by waiting until it is received. - * <p> - * NOTE: We keep checking once every 10ms whether the route is received, - * up to 5 seconds. - * </p> - * - * @param expectedRoute the expected route - * @return the merged BGP route if received within the expected time - * interval, otherwise null - */ - private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute) - throws InterruptedException { - Collection<BgpRouteEntry> bgpRoutes = - bgpSessionManager.getBgpRoutes4(); - - final int maxChecks = 500; // Max wait of 5 seconds - for (int i = 0; i < maxChecks; i++) { - for (BgpRouteEntry bgpRouteEntry : bgpRoutes) { - if (bgpRouteEntry.equals(expectedRoute) && - bgpRouteEntry.getBgpSession() == - expectedRoute.getBgpSession()) { - return bgpRouteEntry; - } - } - Thread.sleep(10); - bgpRoutes = bgpSessionManager.getBgpRoutes4(); - } - - return null; - } - - /** - * Tests that the BGP OPEN messages have been exchanged, followed by - * KEEPALIVE. - * <p> - * The BGP Peer opens the sessions and transmits OPEN Message, eventually - * followed by KEEPALIVE. The tested BGP listener should respond by - * OPEN Message, followed by KEEPALIVE. - * </p> - * - * @throws TestUtilsException TestUtils error - */ - @Test - public void testExchangedBgpOpenMessages() - throws InterruptedException, TestUtilsException { - // Initiate the connections - peer1.connect(connectToSocket); - peer2.connect(connectToSocket); - peer3.connect(connectToSocket); - - // - // Test the fields from the BGP OPEN message: - // BGP version, AS number, BGP ID - // - for (TestBgpPeer peer : peers) { - assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(), - is(BgpConstants.BGP_VERSION)); - assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(), - is(IP_LOOPBACK_ID)); - assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(), - is(TestBgpPeerChannelHandler.PEER_AS)); - } - - // - // Test that the BgpSession instances have been created - // - assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID)); - assertThat(bgpSessionManager.getBgpSessions(), hasSize(3)); - assertThat(bgpSession1, notNullValue()); - assertThat(bgpSession2, notNullValue()); - assertThat(bgpSession3, notNullValue()); - for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) { - long sessionAs = bgpSession.localInfo().asNumber(); - assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS)); - } - } - - - /** - * Tests that the BGP OPEN with Capability messages have been exchanged, - * followed by KEEPALIVE. - * <p> - * The BGP Peer opens the sessions and transmits OPEN Message, eventually - * followed by KEEPALIVE. The tested BGP listener should respond by - * OPEN Message, followed by KEEPALIVE. - * </p> - * - * @throws TestUtilsException TestUtils error - */ - @Test - public void testExchangedBgpOpenCapabilityMessages() - throws InterruptedException, TestUtilsException { - // - // Setup the BGP Capabilities for all peers - // - for (TestBgpPeer peer : peers) { - peer.peerChannelHandler.localInfo.setIpv4Unicast(); - peer.peerChannelHandler.localInfo.setIpv4Multicast(); - peer.peerChannelHandler.localInfo.setIpv6Unicast(); - peer.peerChannelHandler.localInfo.setIpv6Multicast(); - peer.peerChannelHandler.localInfo.setAs4OctetCapability(); - peer.peerChannelHandler.localInfo.setAs4Number( - TestBgpPeerChannelHandler.PEER_AS4); - } - - // Initiate the connections - peer1.connect(connectToSocket); - peer2.connect(connectToSocket); - peer3.connect(connectToSocket); - - // - // Test the fields from the BGP OPEN message: - // BGP version, BGP ID - // - for (TestBgpPeer peer : peers) { - assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(), - is(BgpConstants.BGP_VERSION)); - assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(), - is(IP_LOOPBACK_ID)); - } - - // - // Test that the BgpSession instances have been created, - // and contain the appropriate BGP session information. - // - assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID)); - assertThat(bgpSessionManager.getBgpSessions(), hasSize(3)); - assertThat(bgpSession1, notNullValue()); - assertThat(bgpSession2, notNullValue()); - assertThat(bgpSession3, notNullValue()); - for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) { - BgpSessionInfo localInfo = bgpSession.localInfo(); - assertThat(localInfo.ipv4Unicast(), is(true)); - assertThat(localInfo.ipv4Multicast(), is(true)); - assertThat(localInfo.ipv6Unicast(), is(true)); - assertThat(localInfo.ipv6Multicast(), is(true)); - assertThat(localInfo.as4OctetCapability(), is(true)); - assertThat(localInfo.asNumber(), - is(TestBgpPeerChannelHandler.PEER_AS4)); - assertThat(localInfo.as4Number(), - is(TestBgpPeerChannelHandler.PEER_AS4)); - } - } - - /** - * Tests that the BGP UPDATE messages have been received and processed. - */ - @Test - public void testProcessedBgpUpdateMessages() throws InterruptedException { - ChannelBuffer message; - BgpRouteEntry bgpRouteEntry; - Collection<BgpRouteEntry> bgpRibIn1; - Collection<BgpRouteEntry> bgpRibIn2; - Collection<BgpRouteEntry> bgpRibIn3; - Collection<BgpRouteEntry> bgpRoutes; - - // Initiate the connections - peer1.connect(connectToSocket); - peer2.connect(connectToSocket); - peer3.connect(connectToSocket); - - // Prepare routes to add/delete - Collection<Ip4Prefix> addedRoutes = new LinkedList<>(); - Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>(); - - // - // Add and delete some routes - // - addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0")); - addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8")); - addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16")); - addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24")); - addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32")); - withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8")); - withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16")); - withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24")); - withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32")); - // Write the routes - message = peer1.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP1_ROUTER, - DEFAULT_LOCAL_PREF, - DEFAULT_MULTI_EXIT_DISC, - asPathLong, - addedRoutes, - withdrawnRoutes); - peer1.peerChannelHandler.savedCtx.getChannel().write(message); - // - // Check that the routes have been received, processed and stored - // - bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5); - assertThat(bgpRibIn1, hasSize(5)); - bgpRoutes = waitForBgpRoutes(5); - assertThat(bgpRoutes, hasSize(5)); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("0.0.0.0/0"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("20.0.0.0/8"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("30.0.0.0/16"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("40.0.0.0/24"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("50.0.0.0/32"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - - // - // Delete some routes - // - addedRoutes = new LinkedList<>(); - withdrawnRoutes = new LinkedList<>(); - withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0")); - withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32")); - // Write the routes - message = peer1.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP1_ROUTER, - DEFAULT_LOCAL_PREF, - DEFAULT_MULTI_EXIT_DISC, - asPathLong, - addedRoutes, - withdrawnRoutes); - peer1.peerChannelHandler.savedCtx.getChannel().write(message); - // - // Check that the routes have been received, processed and stored - // - bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3); - assertThat(bgpRibIn1, hasSize(3)); - bgpRoutes = waitForBgpRoutes(3); - assertThat(bgpRoutes, hasSize(3)); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("20.0.0.0/8"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("30.0.0.0/16"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("40.0.0.0/24"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - DEFAULT_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - - - // Close the channels and test there are no routes - peer1.peerChannelHandler.closeChannel(); - peer2.peerChannelHandler.closeChannel(); - peer3.peerChannelHandler.closeChannel(); - bgpRoutes = waitForBgpRoutes(0); - assertThat(bgpRoutes, hasSize(0)); - } - - /** - * Tests the BGP route preference. - */ - @Test - public void testBgpRoutePreference() throws InterruptedException { - ChannelBuffer message; - BgpRouteEntry bgpRouteEntry; - Collection<BgpRouteEntry> bgpRibIn1; - Collection<BgpRouteEntry> bgpRibIn2; - Collection<BgpRouteEntry> bgpRibIn3; - Collection<BgpRouteEntry> bgpRoutes; - Collection<Ip4Prefix> addedRoutes = new LinkedList<>(); - Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>(); - - // Initiate the connections - peer1.connect(connectToSocket); - peer2.connect(connectToSocket); - peer3.connect(connectToSocket); - - // - // Setup the initial set of routes to Peer1 - // - addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8")); - addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16")); - // Write the routes - message = peer1.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP1_ROUTER, - DEFAULT_LOCAL_PREF, - DEFAULT_MULTI_EXIT_DISC, - asPathLong, - addedRoutes, - withdrawnRoutes); - peer1.peerChannelHandler.savedCtx.getChannel().write(message); - bgpRoutes = waitForBgpRoutes(2); - assertThat(bgpRoutes, hasSize(2)); - - // - // Add a route entry to Peer2 with a better LOCAL_PREF - // - addedRoutes = new LinkedList<>(); - withdrawnRoutes = new LinkedList<>(); - addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8")); - // Write the routes - message = peer2.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP2_ROUTER, - BETTER_LOCAL_PREF, - DEFAULT_MULTI_EXIT_DISC, - asPathLong, - addedRoutes, - withdrawnRoutes); - peer2.peerChannelHandler.savedCtx.getChannel().write(message); - // - // Check that the routes have been received, processed and stored - // - bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1); - assertThat(bgpRibIn2, hasSize(1)); - bgpRoutes = waitForBgpRoutes(2); - assertThat(bgpRoutes, hasSize(2)); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession2, - Ip4Prefix.valueOf("20.0.0.0/8"), - NEXT_HOP2_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathLong, - BETTER_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - - // - // Add a route entry to Peer3 with a shorter AS path - // - addedRoutes = new LinkedList<>(); - withdrawnRoutes = new LinkedList<>(); - addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8")); - // Write the routes - message = peer3.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP3_ROUTER, - BETTER_LOCAL_PREF, - DEFAULT_MULTI_EXIT_DISC, - asPathShort, - addedRoutes, - withdrawnRoutes); - peer3.peerChannelHandler.savedCtx.getChannel().write(message); - // - // Check that the routes have been received, processed and stored - // - bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1); - assertThat(bgpRibIn3, hasSize(1)); - bgpRoutes = waitForBgpRoutes(2); - assertThat(bgpRoutes, hasSize(2)); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession3, - Ip4Prefix.valueOf("20.0.0.0/8"), - NEXT_HOP3_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathShort, - BETTER_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC); - assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - - // - // Cleanup in preparation for next test: delete old route entry from - // Peer2 - // - addedRoutes = new LinkedList<>(); - withdrawnRoutes = new LinkedList<>(); - withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8")); - // Write the routes - message = peer2.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP2_ROUTER, - BETTER_LOCAL_PREF, - BETTER_MULTI_EXIT_DISC, - asPathShort, - addedRoutes, - withdrawnRoutes); - peer2.peerChannelHandler.savedCtx.getChannel().write(message); - // - // Check that the routes have been received, processed and stored - // - bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0); - assertThat(bgpRibIn2, hasSize(0)); - - // - // Add a route entry to Peer2 with a better MED - // - addedRoutes = new LinkedList<>(); - withdrawnRoutes = new LinkedList<>(); - addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8")); - // Write the routes - message = peer2.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP2_ROUTER, - BETTER_LOCAL_PREF, - BETTER_MULTI_EXIT_DISC, - asPathShort, - addedRoutes, - withdrawnRoutes); - peer2.peerChannelHandler.savedCtx.getChannel().write(message); - // - // Check that the routes have been received, processed and stored - // - bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1); - assertThat(bgpRibIn2, hasSize(1)); - bgpRoutes = waitForBgpRoutes(2); - assertThat(bgpRoutes, hasSize(2)); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession2, - Ip4Prefix.valueOf("20.0.0.0/8"), - NEXT_HOP2_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathShort, - BETTER_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC); - assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - - // - // Add a route entry to Peer1 with a better (lower) BGP ID - // - addedRoutes = new LinkedList<>(); - withdrawnRoutes = new LinkedList<>(); - addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8")); - withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16")); - // Write the routes - message = peer1.peerChannelHandler.prepareBgpUpdate( - NEXT_HOP1_ROUTER, - BETTER_LOCAL_PREF, - BETTER_MULTI_EXIT_DISC, - asPathShort, - addedRoutes, - withdrawnRoutes); - peer1.peerChannelHandler.savedCtx.getChannel().write(message); - // - // Check that the routes have been received, processed and stored - // - bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1); - assertThat(bgpRibIn1, hasSize(1)); - bgpRoutes = waitForBgpRoutes(1); - assertThat(bgpRoutes, hasSize(1)); - // - bgpRouteEntry = - new BgpRouteEntry(bgpSession1, - Ip4Prefix.valueOf("20.0.0.0/8"), - NEXT_HOP1_ROUTER, - (byte) BgpConstants.Update.Origin.IGP, - asPathShort, - BETTER_LOCAL_PREF); - bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC); - assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry)); - assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue()); - - - // Close the channels and test there are no routes - peer1.peerChannelHandler.closeChannel(); - peer2.peerChannelHandler.closeChannel(); - peer3.peerChannelHandler.closeChannel(); - bgpRoutes = waitForBgpRoutes(0); - assertThat(bgpRoutes, hasSize(0)); - } -} diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java deleted file mode 100644 index 516bf578..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.hamcrest.Matchers; -import org.junit.Test; - -import java.util.ArrayList; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; - -/** - * Unit tests for the BgpRouteEntry.PathSegment class. - */ -public class PathSegmentTest { - /** - * Generates a Path Segment. - * - * @return a generated PathSegment - */ - private BgpRouteEntry.PathSegment generatePathSegment() { - byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(1L); - segmentAsNumbers.add(2L); - segmentAsNumbers.add(3L); - BgpRouteEntry.PathSegment pathSegment = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - - return pathSegment; - } - - /** - * Tests valid class constructor. - */ - @Test - public void testConstructor() { - BgpRouteEntry.PathSegment pathSegment = generatePathSegment(); - - String expectedString = - "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}"; - assertThat(pathSegment.toString(), is(expectedString)); - } - - /** - * Tests invalid class constructor for null Segment AS Numbers. - */ - @Test(expected = NullPointerException.class) - public void testInvalidConstructorNullSegmentAsNumbers() { - byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers = null; - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - } - - /** - * Tests getting the fields of a Path Segment. - */ - @Test - public void testGetFields() { - // Create the fields to compare against - byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(1L); - segmentAsNumbers.add(2L); - segmentAsNumbers.add(3L); - - // Generate the entry to test - BgpRouteEntry.PathSegment pathSegment = generatePathSegment(); - - assertThat(pathSegment.getType(), is(pathSegmentType)); - assertThat(pathSegment.getSegmentAsNumbers(), is(segmentAsNumbers)); - } - - /** - * Tests equality of {@link BgpRouteEntry.PathSegment}. - */ - @Test - public void testEquality() { - BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment(); - BgpRouteEntry.PathSegment pathSegment2 = generatePathSegment(); - - assertThat(pathSegment1, is(pathSegment2)); - } - - /** - * Tests non-equality of {@link BgpRouteEntry.PathSegment}. - */ - @Test - public void testNonEquality() { - BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment(); - - // Setup Path Segment 2 - byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; - ArrayList<Long> segmentAsNumbers = new ArrayList<>(); - segmentAsNumbers.add(1L); - segmentAsNumbers.add(22L); // Different - segmentAsNumbers.add(3L); - // - BgpRouteEntry.PathSegment pathSegment2 = - new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); - - assertThat(pathSegment1, Matchers.is(not(pathSegment2))); - } - - /** - * Tests object string representation. - */ - @Test - public void testToString() { - BgpRouteEntry.PathSegment pathSegment = generatePathSegment(); - - String expectedString = - "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}"; - assertThat(pathSegment.toString(), is(expectedString)); - } -} diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java deleted file mode 100644 index 41485e95..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.SimpleChannelHandler; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; - -import java.util.Collection; - -/** - * Class for handling the remote BGP Peer session. - */ -class TestBgpPeerChannelHandler extends SimpleChannelHandler { - static final long PEER_AS = 65001; - static final long PEER_AS4 = 0x12345678; - static final int PEER_HOLDTIME = 120; // 120 seconds - - final BgpSessionInfo localInfo = new BgpSessionInfo(); - ChannelHandlerContext savedCtx; - - /** - * Constructor for given BGP ID. - * - * @param bgpId the BGP ID to use - */ - TestBgpPeerChannelHandler(Ip4Address bgpId) { - this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION); - this.localInfo.setBgpId(bgpId); - this.localInfo.setAsNumber(PEER_AS); - this.localInfo.setHoldtime(PEER_HOLDTIME); - } - - /** - * Closes the channel. - */ - void closeChannel() { - savedCtx.getChannel().close(); - } - - @Override - public void channelConnected(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - this.savedCtx = ctx; - // Prepare and transmit BGP OPEN message - ChannelBuffer message = BgpOpen.prepareBgpOpen(localInfo); - ctx.getChannel().write(message); - - // Prepare and transmit BGP KEEPALIVE message - message = BgpKeepalive.prepareBgpKeepalive(); - ctx.getChannel().write(message); - } - - @Override - public void channelDisconnected(ChannelHandlerContext ctx, - ChannelStateEvent channelEvent) { - // Nothing to do - } - - /** - * Prepares BGP UPDATE message. - * - * @param nextHopRouter the next-hop router address for the routes to add - * @param localPref the local preference for the routes to use - * @param multiExitDisc the MED value - * @param asPath the AS path for the routes to add - * @param addedRoutes the routes to add - * @param withdrawnRoutes the routes to withdraw - * @return the message to transmit (BGP header included) - */ - ChannelBuffer prepareBgpUpdate(Ip4Address nextHopRouter, - long localPref, - long multiExitDisc, - BgpRouteEntry.AsPath asPath, - Collection<Ip4Prefix> addedRoutes, - Collection<Ip4Prefix> withdrawnRoutes) { - int attrFlags; - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - ChannelBuffer pathAttributes = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // Encode the Withdrawn Routes - ChannelBuffer encodedPrefixes = encodePackedPrefixes(withdrawnRoutes); - message.writeShort(encodedPrefixes.readableBytes()); - message.writeBytes(encodedPrefixes); - - // Encode the Path Attributes - // ORIGIN: IGP - attrFlags = 0x40; // Transitive flag - pathAttributes.writeByte(attrFlags); - pathAttributes.writeByte(BgpConstants.Update.Origin.TYPE); - pathAttributes.writeByte(1); // Data length - pathAttributes.writeByte(BgpConstants.Update.Origin.IGP); - - // AS_PATH: asPath - attrFlags = 0x40; // Transitive flag - pathAttributes.writeByte(attrFlags); - pathAttributes.writeByte(BgpConstants.Update.AsPath.TYPE); - ChannelBuffer encodedAsPath = encodeAsPath(asPath); - pathAttributes.writeByte(encodedAsPath.readableBytes()); // Data length - pathAttributes.writeBytes(encodedAsPath); - // NEXT_HOP: nextHopRouter - attrFlags = 0x40; // Transitive flag - pathAttributes.writeByte(attrFlags); - pathAttributes.writeByte(BgpConstants.Update.NextHop.TYPE); - pathAttributes.writeByte(4); // Data length - pathAttributes.writeInt(nextHopRouter.toInt()); // Next-hop router - // LOCAL_PREF: localPref - attrFlags = 0x40; // Transitive flag - pathAttributes.writeByte(attrFlags); - pathAttributes.writeByte(BgpConstants.Update.LocalPref.TYPE); - pathAttributes.writeByte(4); // Data length - pathAttributes.writeInt((int) localPref); // Preference value - // MULTI_EXIT_DISC: multiExitDisc - attrFlags = 0x80; // Optional - // Non-Transitive flag - pathAttributes.writeByte(attrFlags); - pathAttributes.writeByte(BgpConstants.Update.MultiExitDisc.TYPE); - pathAttributes.writeByte(4); // Data length - pathAttributes.writeInt((int) multiExitDisc); // Preference value - // The NLRI prefixes - encodedPrefixes = encodePackedPrefixes(addedRoutes); - - // Write the Path Attributes, beginning with its length - message.writeShort(pathAttributes.readableBytes()); - message.writeBytes(pathAttributes); - message.writeBytes(encodedPrefixes); - - return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_UPDATE, - message); - } - - /** - * Encodes a collection of IPv4 network prefixes in a packed format. - * <p> - * The IPv4 prefixes are encoded in the form: - * <Length, Prefix> where Length is the length in bits of the IPv4 prefix, - * and Prefix is the IPv4 prefix (padded with trailing bits to the end - * of an octet). - * - * @param prefixes the prefixes to encode - * @return the buffer with the encoded prefixes - */ - private ChannelBuffer encodePackedPrefixes(Collection<Ip4Prefix> prefixes) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - // Write each of the prefixes - for (Ip4Prefix prefix : prefixes) { - int prefixBitlen = prefix.prefixLength(); - int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up - message.writeByte(prefixBitlen); - - Ip4Address address = prefix.address(); - long value = address.toInt() & 0xffffffffL; - for (int i = 0; i < Ip4Address.BYTE_LENGTH; i++) { - if (prefixBytelen-- == 0) { - break; - } - long nextByte = - (value >> ((Ip4Address.BYTE_LENGTH - i - 1) * 8)) & 0xff; - message.writeByte((int) nextByte); - } - } - - return message; - } - - /** - * Encodes an AS path. - * - * @param asPath the AS path to encode - * @return the buffer with the encoded AS path - */ - private ChannelBuffer encodeAsPath(BgpRouteEntry.AsPath asPath) { - ChannelBuffer message = - ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); - - for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) { - message.writeByte(pathSegment.getType()); - message.writeByte(pathSegment.getSegmentAsNumbers().size()); - for (Long asNumber : pathSegment.getSegmentAsNumbers()) { - message.writeShort(asNumber.intValue()); - } - } - - return message; - } -} diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java deleted file mode 100644 index b4ff40d2..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2014-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.routing.bgp; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.onlab.packet.Ip4Address; - -import java.util.concurrent.CountDownLatch; - -/** - * Class for handling the decoding of the BGP messages at the remote - * BGP peer session. - */ -class TestBgpPeerFrameDecoder extends FrameDecoder { - final BgpSessionInfo remoteInfo = new BgpSessionInfo(); - - final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1); - final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1); - - @Override - protected Object decode(ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { - // Test for minimum length of the BGP message - if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) { - // No enough data received - return null; - } - - // - // Mark the current buffer position in case we haven't received - // the whole message. - // - buf.markReaderIndex(); - - // - // Read and check the BGP message Marker field: it must be all ones - // - byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH]; - buf.readBytes(marker); - for (int i = 0; i < marker.length; i++) { - if (marker[i] != (byte) 0xff) { - // ERROR: Connection Not Synchronized. Close the channel. - ctx.getChannel().close(); - return null; - } - } - - // - // Read and check the BGP message Length field - // - int length = buf.readUnsignedShort(); - if ((length < BgpConstants.BGP_HEADER_LENGTH) || - (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) { - // ERROR: Bad Message Length. Close the channel. - ctx.getChannel().close(); - return null; - } - - // - // Test whether the rest of the message is received: - // So far we have read the Marker (16 octets) and the - // Length (2 octets) fields. - // - int remainingMessageLen = - length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2; - if (buf.readableBytes() < remainingMessageLen) { - // No enough data received - buf.resetReaderIndex(); - return null; - } - - // - // Read the BGP message Type field, and process based on that type - // - int type = buf.readUnsignedByte(); - remainingMessageLen--; // Adjust after reading the type - ChannelBuffer message = buf.readBytes(remainingMessageLen); - - // - // Process the remaining of the message based on the message type - // - switch (type) { - case BgpConstants.BGP_TYPE_OPEN: - processBgpOpen(ctx, message); - break; - case BgpConstants.BGP_TYPE_UPDATE: - // NOTE: Not used as part of the test, because ONOS does not - // originate UPDATE messages. - break; - case BgpConstants.BGP_TYPE_NOTIFICATION: - // NOTE: Not used as part of the testing (yet) - break; - case BgpConstants.BGP_TYPE_KEEPALIVE: - processBgpKeepalive(ctx, message); - break; - default: - // ERROR: Bad Message Type. Close the channel. - ctx.getChannel().close(); - return null; - } - - return null; - } - - /** - * Processes BGP OPEN message. - * - * @param ctx the Channel Handler Context. - * @param message the message to process. - */ - private void processBgpOpen(ChannelHandlerContext ctx, - ChannelBuffer message) { - int minLength = - BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH; - if (message.readableBytes() < minLength) { - // ERROR: Bad Message Length. Close the channel. - ctx.getChannel().close(); - return; - } - - // - // Parse the OPEN message - // - remoteInfo.setBgpVersion(message.readUnsignedByte()); - remoteInfo.setAsNumber(message.readUnsignedShort()); - remoteInfo.setHoldtime(message.readUnsignedShort()); - remoteInfo.setBgpId(Ip4Address.valueOf((int) message.readUnsignedInt())); - // Optional Parameters - int optParamLen = message.readUnsignedByte(); - if (message.readableBytes() < optParamLen) { - // ERROR: Bad Message Length. Close the channel. - ctx.getChannel().close(); - return; - } - message.readBytes(optParamLen); // NOTE: data ignored - - // BGP OPEN message successfully received - receivedOpenMessageLatch.countDown(); - } - - /** - * Processes BGP KEEPALIVE message. - * - * @param ctx the Channel Handler Context. - * @param message the message to process. - */ - private void processBgpKeepalive(ChannelHandlerContext ctx, - ChannelBuffer message) { - if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH != - BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) { - // ERROR: Bad Message Length. Close the channel. - ctx.getChannel().close(); - return; - } - // BGP KEEPALIVE message successfully received - receivedKeepaliveMessageLatch.countDown(); - } -} diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/impl/RouterAsyncArpTest.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/impl/RouterAsyncArpTest.java deleted file mode 100644 index 100c13d4..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/impl/RouterAsyncArpTest.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2014-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.routing.impl; - -import com.google.common.collect.Sets; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onlab.packet.VlanId; -import org.onosproject.core.CoreService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DefaultHost; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -import org.onosproject.net.HostId; -import org.onosproject.net.HostLocation; -import org.onosproject.net.PortNumber; -import org.onosproject.net.host.HostEvent; -import org.onosproject.net.host.HostListener; -import org.onosproject.net.host.HostService; -import org.onosproject.net.provider.ProviderId; -import org.onosproject.routing.config.RoutingConfigurationService; -import org.onosproject.routing.impl.Router.InternalHostListener; -import org.onosproject.routing.BgpService; -import org.onosproject.routing.FibEntry; -import org.onosproject.routing.FibListener; -import org.onosproject.routing.FibUpdate; -import org.onosproject.routing.RouteEntry; -import org.onosproject.routing.RouteListener; -import org.onosproject.routing.RouteUpdate; - -import java.util.Collections; - -import static org.easymock.EasyMock.*; - -/** -* This class tests adding a route and updating a route. -* The HostService module answers the MAC address asynchronously. -*/ -public class RouterAsyncArpTest { - - private HostService hostService; - private FibListener fibListener; - private RoutingConfigurationService routingConfigurationService; - - private static final ConnectPoint SW1_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000001"), - PortNumber.portNumber(1)); - - private static final ConnectPoint SW2_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000002"), - PortNumber.portNumber(1)); - - private static final ConnectPoint SW3_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000003"), - PortNumber.portNumber(1)); - - private Router router; - private InternalHostListener internalHostListener; - - @Before - public void setUp() throws Exception { - hostService = createMock(HostService.class); - routingConfigurationService = - createMock(RoutingConfigurationService.class); - - BgpService bgpService = createMock(BgpService.class); - bgpService.start(anyObject(RouteListener.class)); - bgpService.stop(); - replay(bgpService); - - fibListener = createMock(FibListener.class); - - router = new Router(); - router.coreService = createNiceMock(CoreService.class); - router.hostService = hostService; - router.routingConfigurationService = routingConfigurationService; - router.bgpService = bgpService; - router.activate(); - - router.addFibListener(fibListener); - router.start(); - - internalHostListener = router.new InternalHostListener(); - } - - @After - public void tearDown() { - // Called during shutdown - reset(hostService); - hostService.removeListener(anyObject(HostListener.class)); - - router.stop(); - } - - /** - * Tests adding a route entry with asynchronous HostService replies. - */ - @Test - public void testRouteAdd() { - // Construct a route entry - IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24"); - IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1"); - - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); - - // Host service will reply with no hosts when asked - reset(hostService); - expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn( - Collections.emptySet()).anyTimes(); - hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1")); - replay(hostService); - - reset(routingConfigurationService); - expect(routingConfigurationService.isIpPrefixLocal( - anyObject(IpPrefix.class))).andReturn(false); - replay(routingConfigurationService); - - // Initially when we add the route, no FIB update will be sent - replay(fibListener); - - router.processRouteUpdates(Collections.singletonList( - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); - - verify(fibListener); - - - // Now when we send the event, we expect the FIB update to be sent - reset(fibListener); - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, - MacAddress.valueOf("00:00:00:00:00:01")); - - fibListener.update(Collections.singletonList(new FibUpdate( - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); - replay(fibListener); - - Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE, - new HostLocation( - SW1_ETH1.deviceId(), - SW1_ETH1.port(), 1), - Sets.newHashSet(IpAddress.valueOf("192.168.10.1"))); - - // Send in the host event - internalHostListener.event( - new HostEvent(HostEvent.Type.HOST_ADDED, host)); - - verify(fibListener); - } - - /** - * Tests updating a route entry with asynchronous HostService replies. - */ - @Test - public void testRouteUpdate() { - // Add a route - testRouteAdd(); - - // Construct a route entry - IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24"); - IpAddress nextHopIp = Ip4Address.valueOf("192.168.20.1"); - - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); - - // Host service will reply with no hosts when asked - reset(hostService); - expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn( - Collections.emptySet()).anyTimes(); - hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1")); - replay(hostService); - - reset(routingConfigurationService); - expect(routingConfigurationService.isIpPrefixLocal( - anyObject(IpPrefix.class))).andReturn(false); - replay(routingConfigurationService); - - // Initially when we add the route, the DELETE FIB update will be sent - // but the UPDATE FIB update will come later when the MAC is resolved - reset(fibListener); - - fibListener.update(Collections.emptyList(), Collections.singletonList(new FibUpdate( - FibUpdate.Type.DELETE, new FibEntry(prefix, null, null)))); - replay(fibListener); - - router.processRouteUpdates(Collections.singletonList( - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); - - verify(fibListener); - - - // Now when we send the event, we expect the FIB update to be sent - reset(fibListener); - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, - MacAddress.valueOf("00:00:00:00:00:02")); - - fibListener.update(Collections.singletonList(new FibUpdate( - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); - replay(fibListener); - - Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE, - new HostLocation( - SW1_ETH1.deviceId(), - SW1_ETH1.port(), 1), - Sets.newHashSet(IpAddress.valueOf("192.168.20.1"))); - - // Send in the host event - internalHostListener.event( - new HostEvent(HostEvent.Type.HOST_ADDED, host)); - - verify(fibListener); - } -} diff --git a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/impl/RouterTest.java b/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/impl/RouterTest.java deleted file mode 100644 index c73e18cb..00000000 --- a/framework/src/onos/apps/routing/src/test/java/org/onosproject/routing/impl/RouterTest.java +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright 2014-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.routing.impl; - -import com.google.common.collect.Sets; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.Ip6Address; -import org.onlab.packet.Ip6Prefix; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onlab.packet.VlanId; -import org.onosproject.core.CoreService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DefaultHost; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -import org.onosproject.net.HostId; -import org.onosproject.net.HostLocation; -import org.onosproject.net.PortNumber; -import org.onosproject.net.host.HostListener; -import org.onosproject.net.host.HostService; -import org.onosproject.net.provider.ProviderId; -import org.onosproject.routing.BgpService; -import org.onosproject.routing.FibEntry; -import org.onosproject.routing.FibListener; -import org.onosproject.routing.FibUpdate; -import org.onosproject.routing.RouteEntry; -import org.onosproject.routing.RouteListener; -import org.onosproject.routing.RouteUpdate; -import org.onosproject.routing.config.RoutingConfigurationService; - -import java.util.Collections; - -import static org.easymock.EasyMock.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * This class tests adding a route, updating a route, deleting a route, - * and adding a route whose next hop is the local BGP speaker. - * <p/> - * The HostService answers requests synchronously. - */ -public class RouterTest { - - private HostService hostService; - private RoutingConfigurationService routingConfigurationService; - - private FibListener fibListener; - - private static final ConnectPoint SW1_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000001"), - PortNumber.portNumber(1)); - - private static final ConnectPoint SW2_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000002"), - PortNumber.portNumber(1)); - - private static final ConnectPoint SW3_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000003"), - PortNumber.portNumber(1)); - - private static final ConnectPoint SW4_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000004"), - PortNumber.portNumber(1)); - - private static final ConnectPoint SW5_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000005"), - PortNumber.portNumber(1)); - - private static final ConnectPoint SW6_ETH1 = new ConnectPoint( - DeviceId.deviceId("of:0000000000000006"), - PortNumber.portNumber(1)); - private Router router; - - @Before - public void setUp() throws Exception { - setUpHostService(); - routingConfigurationService = - createMock(RoutingConfigurationService.class); - - BgpService bgpService = createMock(BgpService.class); - bgpService.start(anyObject(RouteListener.class)); - bgpService.stop(); - replay(bgpService); - - fibListener = createMock(FibListener.class); - - router = new Router(); - router.coreService = createNiceMock(CoreService.class); - router.hostService = hostService; - router.routingConfigurationService = routingConfigurationService; - router.bgpService = bgpService; - router.activate(); - - router.addFibListener(fibListener); - router.start(); - } - - @After - public void tearDown() { - router.stop(); - } - - /** - * Sets up the host service with details of some hosts. - */ - private void setUpHostService() { - hostService = createMock(HostService.class); - - hostService.addListener(anyObject(HostListener.class)); - expectLastCall().anyTimes(); - - IpAddress host1Address = IpAddress.valueOf("192.168.10.1"); - Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE, - new HostLocation(SW1_ETH1, 1), - Sets.newHashSet(host1Address)); - - expect(hostService.getHostsByIp(host1Address)) - .andReturn(Sets.newHashSet(host1)).anyTimes(); - hostService.startMonitoringIp(host1Address); - expectLastCall().anyTimes(); - - IpAddress host2Address = IpAddress.valueOf("192.168.20.1"); - Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE, - new HostLocation(SW2_ETH1, 1), - Sets.newHashSet(host2Address)); - - expect(hostService.getHostsByIp(host2Address)) - .andReturn(Sets.newHashSet(host2)).anyTimes(); - hostService.startMonitoringIp(host2Address); - expectLastCall().anyTimes(); - - // Next hop on a VLAN - IpAddress host3Address = IpAddress.valueOf("192.168.40.1"); - Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:03"), VlanId.vlanId((short) 1), - new HostLocation(SW3_ETH1, 1), - Sets.newHashSet(host3Address)); - - expect(hostService.getHostsByIp(host3Address)) - .andReturn(Sets.newHashSet(host3)).anyTimes(); - hostService.startMonitoringIp(host3Address); - expectLastCall().anyTimes(); - - IpAddress host4Address = IpAddress.valueOf("1000::1"); - Host host4 = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE, - new HostLocation(SW4_ETH1, 1), - Sets.newHashSet(host4Address)); - - expect(hostService.getHostsByIp(host4Address)) - .andReturn(Sets.newHashSet(host4)).anyTimes(); - hostService.startMonitoringIp(host4Address); - expectLastCall().anyTimes(); - - IpAddress host5Address = IpAddress.valueOf("2000::1"); - Host host5 = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:05"), VlanId.NONE, - new HostLocation(SW5_ETH1, 1), - Sets.newHashSet(host5Address)); - - expect(hostService.getHostsByIp(host5Address)) - .andReturn(Sets.newHashSet(host5)).anyTimes(); - hostService.startMonitoringIp(host5Address); - expectLastCall().anyTimes(); - - // Next hop on a VLAN - IpAddress host6Address = IpAddress.valueOf("3000::1"); - Host host6 = new DefaultHost(ProviderId.NONE, HostId.NONE, - MacAddress.valueOf("00:00:00:00:00:06"), VlanId.vlanId((short) 1), - new HostLocation(SW6_ETH1, 1), - Sets.newHashSet(host6Address)); - - expect(hostService.getHostsByIp(host6Address)) - .andReturn(Sets.newHashSet(host6)).anyTimes(); - hostService.startMonitoringIp(host6Address); - expectLastCall().anyTimes(); - - - // Called during shutdown - hostService.removeListener(anyObject(HostListener.class)); - - replay(hostService); - } - - /** - * Tests adding a IPv4 route entry. - */ - @Test - public void testIpv4RouteAdd() { - // Construct a route entry - IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24"); - IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1"); - - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); - - // Expected FIB entry - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, - MacAddress.valueOf("00:00:00:00:00:01")); - - fibListener.update(Collections.singletonList(new FibUpdate( - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); - - replay(fibListener); - - router.processRouteUpdates(Collections.singletonList( - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); - - verify(fibListener); - } - - - /** - * Tests adding a IPv6 route entry. - */ - @Test - public void testIpv6RouteAdd() { - // Construct a route entry - IpPrefix prefix = Ip6Prefix.valueOf("4000::/64"); - IpAddress nextHopIp = Ip6Address.valueOf("1000::1"); - - RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp); - - // Expected FIB entry - FibEntry fibEntry = new FibEntry(prefix, nextHopIp, - MacAddress.valueOf("00:00:00:00:00:04")); - - fibListener.update(Collections.singletonList(new FibUpdate( - FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList()); - - replay(fibListener); - - router.processRouteUpdates(Collections.singletonList( - new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry))); - - verify(fibListener); - } - - - /** - * Tests updating a IPv4 route entry. - */ - @Test - public void testRouteUpdate() { - // Firstly add a route - testIpv4RouteAdd(); - - // Route entry with updated next hop for the original prefix - RouteEntry routeEntryUpdate = new RouteEntry( - Ip4Prefix.valueOf("1.1.1.0/24"), - Ip4Address.valueOf("192.168.20.1")); - - // The old FIB entry will be withdrawn - FibEntry withdrawFibEntry = new FibEntry( - Ip4Prefix.valueOf("1.1.1.0/24"), null, null); - - // A new FIB entry will be added - FibEntry updateFibEntry = new FibEntry( - Ip4Prefix.valueOf("1.1.1.0/24"), - Ip4Address.valueOf("192.168.20.1"), - MacAddress.valueOf("00:00:00:00:00:02")); - - reset(fibListener); - fibListener.update(Collections.singletonList(new FibUpdate( - FibUpdate.Type.UPDATE, updateFibEntry)), - Collections.singletonList(new FibUpdate( - FibUpdate.Type.DELETE, withdrawFibEntry))); - replay(fibListener); - - reset(routingConfigurationService); - expect(routingConfigurationService.isIpPrefixLocal( - anyObject(IpPrefix.class))).andReturn(false); - replay(routingConfigurationService); - - router.processRouteUpdates(Collections.singletonList(new RouteUpdate( - RouteUpdate.Type.UPDATE, routeEntryUpdate))); - - verify(fibListener); - } - - /** - * Tests updating a IPv6 route entry. - */ - @Test - public void testIpv6RouteUpdate() { - // Firstly add a route - testIpv6RouteAdd(); - - // Route entry with updated next hop for the original prefix - RouteEntry routeEntryUpdate = new RouteEntry( - Ip6Prefix.valueOf("4000::/64"), - Ip6Address.valueOf("2000::1")); - - // The old FIB entry will be withdrawn - FibEntry withdrawFibEntry = new FibEntry( - Ip6Prefix.valueOf("4000::/64"), null, null); - - // A new FIB entry will be added - FibEntry updateFibEntry = new FibEntry( - Ip6Prefix.valueOf("4000::/64"), - Ip6Address.valueOf("2000::1"), - MacAddress.valueOf("00:00:00:00:00:05")); - - reset(fibListener); - fibListener.update(Collections.singletonList(new FibUpdate( - FibUpdate.Type.UPDATE, updateFibEntry)), - Collections.singletonList(new FibUpdate( - FibUpdate.Type.DELETE, withdrawFibEntry))); - replay(fibListener); - - reset(routingConfigurationService); - expect(routingConfigurationService.isIpPrefixLocal( - anyObject(IpPrefix.class))).andReturn(false); - replay(routingConfigurationService); - - router.processRouteUpdates(Collections.singletonList(new RouteUpdate( - RouteUpdate.Type.UPDATE, routeEntryUpdate))); - - verify(fibListener); - } - - /** - * Tests deleting a IPv4 route entry. - */ - @Test - public void testIpv4RouteDelete() { - // Firstly add a route - testIpv4RouteAdd(); - - RouteEntry deleteRouteEntry = new RouteEntry( - Ip4Prefix.valueOf("1.1.1.0/24"), - Ip4Address.valueOf("192.168.10.1")); - - FibEntry deleteFibEntry = new FibEntry( - Ip4Prefix.valueOf("1.1.1.0/24"), null, null); - - reset(fibListener); - fibListener.update(Collections.emptyList(), Collections.singletonList( - new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry))); - - replay(fibListener); - - router.processRouteUpdates(Collections.singletonList( - new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry))); - - verify(fibListener); - } - - /** - * Tests deleting a IPv6 route entry. - */ - @Test - public void testIpv6RouteDelete() { - // Firstly add a route - testIpv6RouteAdd(); - - RouteEntry deleteRouteEntry = new RouteEntry( - Ip6Prefix.valueOf("4000::/64"), - Ip6Address.valueOf("1000::1")); - - FibEntry deleteFibEntry = new FibEntry( - Ip6Prefix.valueOf("4000::/64"), null, null); - - reset(fibListener); - fibListener.update(Collections.emptyList(), Collections.singletonList( - new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry))); - - replay(fibListener); - - router.processRouteUpdates(Collections.singletonList( - new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry))); - - verify(fibListener); - } - - /** - * Tests adding a IPv4 route whose next hop is the local BGP speaker. - */ - @Test - public void testIpv4LocalRouteAdd() { - // Construct a route entry, the next hop is the local BGP speaker - RouteEntry routeEntry = new RouteEntry( - Ip4Prefix.valueOf("1.1.1.0/24"), - Ip4Address.valueOf("0.0.0.0")); - - // No methods on the FIB listener should be called - replay(fibListener); - - reset(routingConfigurationService); - expect(routingConfigurationService.isIpPrefixLocal( - anyObject(IpPrefix.class))).andReturn(true); - replay(routingConfigurationService); - - // Call the processRouteUpdates() method in Router class - RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, - routeEntry); - router.processRouteUpdates(Collections.singletonList(routeUpdate)); - - // Verify - assertEquals(1, router.getRoutes4().size()); - assertTrue(router.getRoutes4().contains(routeEntry)); - verify(fibListener); - } - - /** - * Tests adding a IPv6 route whose next hop is the local BGP speaker. - */ - @Test - public void testIpv6LocalRouteAdd() { - // Construct a route entry, the next hop is the local BGP speaker - RouteEntry routeEntry = new RouteEntry( - Ip6Prefix.valueOf("4000::/64"), - Ip6Address.valueOf("::")); - - // No methods on the FIB listener should be called - replay(fibListener); - - reset(routingConfigurationService); - expect(routingConfigurationService.isIpPrefixLocal( - anyObject(IpPrefix.class))).andReturn(true); - replay(routingConfigurationService); - - // Call the processRouteUpdates() method in Router class - RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, - routeEntry); - router.processRouteUpdates(Collections.singletonList(routeUpdate)); - - // Verify - assertEquals(1, router.getRoutes6().size()); - assertTrue(router.getRoutes6().contains(routeEntry)); - verify(fibListener); - } -} |