Search in sources :

Example 1 with Ip4Address

use of org.onlab.packet.Ip4Address in project onos by opennetworkinglab.

the class BgpOpen method processBgpOpen.

/**
 * 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());
    // 
    if (bgpSession.remoteInfo().as4OctetCapability()) {
        long as4Number = bgpSession.remoteInfo().as4Number();
        bgpSession.remoteInfo().setAsNumber(as4Number);
        bgpSession.localInfo().setAsNumber(as4Number);
    }
    // 
    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);
}
Also used : Ip4Address(org.onlab.packet.Ip4Address) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer)

Example 2 with Ip4Address

use of org.onlab.packet.Ip4Address in project onos by opennetworkinglab.

the class BgpRouteEntry method isBetterThan.

/**
 * 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 if same route
        return true;
    }
    // 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()) {
            // AS number is different
            break medLabel;
        }
        if (thisNeighborAs == BgpConstants.BGP_AS_0) {
            // Invalid AS number
            break medLabel;
        }
        // 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);
    }
    // Routes are same. Shouldn't happen?
    return true;
}
Also used : Ip4Address(org.onlab.packet.Ip4Address)

Example 3 with Ip4Address

use of org.onlab.packet.Ip4Address in project onos by opennetworkinglab.

the class BgpSessionManager method peerConnected.

/**
 * 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) {
        // Duplicate BGP session
        return false;
    }
    bgpSessions.put(bgpSession.remoteInfo().address(), bgpSession);
    // 
    if (bgpSession.localInfo().address() instanceof InetSocketAddress) {
        InetAddress inetAddr = ((InetSocketAddress) bgpSession.localInfo().address()).getAddress();
        Ip4Address ip4Address = Ip4Address.valueOf(inetAddr.getAddress());
        updateMyBgpId(ip4Address);
    }
    return true;
}
Also used : InetSocketAddress(java.net.InetSocketAddress) Ip4Address(org.onlab.packet.Ip4Address) InetAddress(java.net.InetAddress)

Example 4 with Ip4Address

use of org.onlab.packet.Ip4Address in project onos by opennetworkinglab.

the class RouteEntryTest method testInvalidConstructorNullIpv4Prefix.

/**
 * Tests invalid class constructor for null IPv4 prefix.
 */
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullIpv4Prefix() {
    Ip4Prefix prefix = null;
    Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
    new RouteEntry(prefix, nextHop);
}
Also used : Ip4Address(org.onlab.packet.Ip4Address) Ip4Prefix(org.onlab.packet.Ip4Prefix) Test(org.junit.Test)

Example 5 with Ip4Address

use of org.onlab.packet.Ip4Address in project onos by opennetworkinglab.

the class RouteEntryTest method testNonEquality.

/**
 * Tests non-equality of {@link RouteEntry}.
 */
@Test
public void testNonEquality() {
    Ip4Prefix prefix1 = Ip4Prefix.valueOf("1.2.3.0/24");
    Ip4Address nextHop1 = Ip4Address.valueOf("5.6.7.8");
    RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1);
    // Different
    Ip4Prefix prefix2 = Ip4Prefix.valueOf("1.2.3.0/25");
    Ip4Address nextHop2 = Ip4Address.valueOf("5.6.7.8");
    RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2);
    Ip4Prefix prefix3 = Ip4Prefix.valueOf("1.2.3.0/24");
    // Different
    Ip4Address nextHop3 = Ip4Address.valueOf("5.6.7.9");
    RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3);
    assertThat(routeEntry1, Matchers.is(Matchers.not(routeEntry2)));
    assertThat(routeEntry1, Matchers.is(Matchers.not(routeEntry3)));
    Ip6Prefix prefix4 = Ip6Prefix.valueOf("1000::/64");
    Ip6Address nextHop4 = Ip6Address.valueOf("2000::1");
    RouteEntry routeEntry4 = new RouteEntry(prefix4, nextHop4);
    Ip6Prefix prefix5 = Ip6Prefix.valueOf("1000::/65");
    Ip6Address nextHop5 = Ip6Address.valueOf("2000::1");
    RouteEntry routeEntry5 = new RouteEntry(prefix5, nextHop5);
    Ip6Prefix prefix6 = Ip6Prefix.valueOf("1000::/64");
    Ip6Address nextHop6 = Ip6Address.valueOf("2000::2");
    RouteEntry routeEntry6 = new RouteEntry(prefix6, nextHop6);
    assertThat(routeEntry4, Matchers.is(Matchers.not(routeEntry5)));
    assertThat(routeEntry4, Matchers.is(Matchers.not(routeEntry6)));
}
Also used : Ip6Prefix(org.onlab.packet.Ip6Prefix) Ip6Address(org.onlab.packet.Ip6Address) Ip4Address(org.onlab.packet.Ip4Address) Ip4Prefix(org.onlab.packet.Ip4Prefix) Test(org.junit.Test)

Aggregations

Ip4Address (org.onlab.packet.Ip4Address)79 Test (org.junit.Test)29 Ip4Prefix (org.onlab.packet.Ip4Prefix)20 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)15 ArrayList (java.util.ArrayList)14 LinkedList (java.util.LinkedList)12 ProtocolType (org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType)12 BgpPathAttributes (org.onosproject.bgpio.protocol.ver4.BgpPathAttributes)12 AsPath (org.onosproject.bgpio.types.AsPath)12 BgpHeader (org.onosproject.bgpio.types.BgpHeader)12 BgpValueType (org.onosproject.bgpio.types.BgpValueType)12 LinkStateAttributes (org.onosproject.bgpio.types.LinkStateAttributes)12 Med (org.onosproject.bgpio.types.Med)12 MpReachNlri (org.onosproject.bgpio.types.MpReachNlri)12 Origin (org.onosproject.bgpio.types.Origin)12 OriginType (org.onosproject.bgpio.types.Origin.OriginType)12 Ip6Address (org.onlab.packet.Ip6Address)11 MacAddress (org.onlab.packet.MacAddress)10 IpAddress (org.onlab.packet.IpAddress)8 IpPrefix (org.onlab.packet.IpPrefix)8