Showing
9 changed files
with
183 additions
and
1 deletions
| ... | @@ -126,6 +126,8 @@ public class Router implements RouteListener { | ... | @@ -126,6 +126,8 @@ public class Router implements RouteListener { |
| 126 | bgpIntentsSynchronizerExecutor = Executors.newSingleThreadExecutor( | 126 | bgpIntentsSynchronizerExecutor = Executors.newSingleThreadExecutor( |
| 127 | new ThreadFactoryBuilder() | 127 | new ThreadFactoryBuilder() |
| 128 | .setNameFormat("bgp-intents-synchronizer-%d").build()); | 128 | .setNameFormat("bgp-intents-synchronizer-%d").build()); |
| 129 | + | ||
| 130 | + this.hostService.addListener(new InternalHostListener()); | ||
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | /** | 133 | /** | ... | ... |
| ... | @@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 10 | import org.onlab.onos.net.host.HostService; | 10 | import org.onlab.onos.net.host.HostService; |
| 11 | import org.onlab.onos.net.intent.IntentService; | 11 | import org.onlab.onos.net.intent.IntentService; |
| 12 | import org.onlab.onos.sdnip.RouteUpdate.Type; | 12 | import org.onlab.onos.sdnip.RouteUpdate.Type; |
| 13 | +import org.onlab.onos.sdnip.bgp.BgpSessionManager; | ||
| 13 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; | 14 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; |
| 14 | import org.onlab.packet.IpAddress; | 15 | import org.onlab.packet.IpAddress; |
| 15 | import org.onlab.packet.IpPrefix; | 16 | import org.onlab.packet.IpPrefix; |
| ... | @@ -32,6 +33,7 @@ public class SdnIp { | ... | @@ -32,6 +33,7 @@ public class SdnIp { |
| 32 | private SdnIpConfigReader config; | 33 | private SdnIpConfigReader config; |
| 33 | private PeerConnectivity peerConnectivity; | 34 | private PeerConnectivity peerConnectivity; |
| 34 | private Router router; | 35 | private Router router; |
| 36 | + private BgpSessionManager bgpSessionManager; | ||
| 35 | 37 | ||
| 36 | @Activate | 38 | @Activate |
| 37 | protected void activate() { | 39 | protected void activate() { |
| ... | @@ -48,6 +50,9 @@ public class SdnIp { | ... | @@ -48,6 +50,9 @@ public class SdnIp { |
| 48 | router = new Router(intentService, hostService, config, interfaceService); | 50 | router = new Router(intentService, hostService, config, interfaceService); |
| 49 | router.start(); | 51 | router.start(); |
| 50 | 52 | ||
| 53 | + bgpSessionManager = new BgpSessionManager(router); | ||
| 54 | + bgpSessionManager.startUp(2000); // TODO | ||
| 55 | + | ||
| 51 | // TODO need to disable link discovery on external ports | 56 | // TODO need to disable link discovery on external ports |
| 52 | 57 | ||
| 53 | router.update(new RouteUpdate(Type.UPDATE, new RouteEntry( | 58 | router.update(new RouteUpdate(Type.UPDATE, new RouteEntry( | ... | ... |
This diff is collapsed. Click to expand it.
| 1 | +package org.onlab.onos.sdnip.bgp; | ||
| 2 | + | ||
| 3 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
| 4 | +import org.jboss.netty.buffer.ChannelBuffers; | ||
| 5 | +import org.jboss.netty.channel.Channel; | ||
| 6 | +import org.jboss.netty.channel.ChannelHandlerContext; | ||
| 7 | +import org.jboss.netty.handler.codec.frame.FrameDecoder; | ||
| 8 | +import org.onlab.onos.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError; | ||
| 9 | +import org.slf4j.Logger; | ||
| 10 | +import org.slf4j.LoggerFactory; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * Class for handling the decoding of the BGP messages. | ||
| 14 | + */ | ||
| 15 | +class BgpFrameDecoder extends FrameDecoder { | ||
| 16 | + private static final Logger log = | ||
| 17 | + LoggerFactory.getLogger(BgpFrameDecoder.class); | ||
| 18 | + | ||
| 19 | + private final BgpSession bgpSession; | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * Constructor for a given BGP Session. | ||
| 23 | + * | ||
| 24 | + * @param bgpSession the BGP session state to use. | ||
| 25 | + */ | ||
| 26 | + BgpFrameDecoder(BgpSession bgpSession) { | ||
| 27 | + this.bgpSession = bgpSession; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + @Override | ||
| 31 | + protected Object decode(ChannelHandlerContext ctx, | ||
| 32 | + Channel channel, | ||
| 33 | + ChannelBuffer buf) throws Exception { | ||
| 34 | + // | ||
| 35 | + // NOTE: If we close the channel during the decoding, we might still | ||
| 36 | + // see some incoming messages while the channel closing is completed. | ||
| 37 | + // | ||
| 38 | + if (bgpSession.isClosed()) { | ||
| 39 | + return null; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + log.trace("BGP Peer: decode(): remoteAddr = {} localAddr = {} " + | ||
| 43 | + "messageSize = {}", | ||
| 44 | + ctx.getChannel().getRemoteAddress(), | ||
| 45 | + ctx.getChannel().getLocalAddress(), | ||
| 46 | + buf.readableBytes()); | ||
| 47 | + | ||
| 48 | + // Test for minimum length of the BGP message | ||
| 49 | + if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) { | ||
| 50 | + // No enough data received | ||
| 51 | + return null; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + // | ||
| 55 | + // Mark the current buffer position in case we haven't received | ||
| 56 | + // the whole message. | ||
| 57 | + // | ||
| 58 | + buf.markReaderIndex(); | ||
| 59 | + | ||
| 60 | + // | ||
| 61 | + // Read and check the BGP message Marker field: it must be all ones | ||
| 62 | + // (See RFC 4271, Section 4.1) | ||
| 63 | + // | ||
| 64 | + byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH]; | ||
| 65 | + buf.readBytes(marker); | ||
| 66 | + for (int i = 0; i < marker.length; i++) { | ||
| 67 | + if (marker[i] != (byte) 0xff) { | ||
| 68 | + log.debug("BGP RX Error: invalid marker {} at position {}", | ||
| 69 | + marker[i], i); | ||
| 70 | + // | ||
| 71 | + // ERROR: Connection Not Synchronized | ||
| 72 | + // | ||
| 73 | + // Send NOTIFICATION and close the connection | ||
| 74 | + int errorCode = MessageHeaderError.ERROR_CODE; | ||
| 75 | + int errorSubcode = | ||
| 76 | + MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED; | ||
| 77 | + ChannelBuffer txMessage = | ||
| 78 | + bgpSession.prepareBgpNotification(errorCode, errorSubcode, | ||
| 79 | + null); | ||
| 80 | + ctx.getChannel().write(txMessage); | ||
| 81 | + bgpSession.closeChannel(ctx); | ||
| 82 | + return null; | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + // | ||
| 87 | + // Read and check the BGP message Length field | ||
| 88 | + // | ||
| 89 | + int length = buf.readUnsignedShort(); | ||
| 90 | + if ((length < BgpConstants.BGP_HEADER_LENGTH) || | ||
| 91 | + (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) { | ||
| 92 | + log.debug("BGP RX Error: invalid Length field {}. " + | ||
| 93 | + "Must be between {} and {}", | ||
| 94 | + length, | ||
| 95 | + BgpConstants.BGP_HEADER_LENGTH, | ||
| 96 | + BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
| 97 | + // | ||
| 98 | + // ERROR: Bad Message Length | ||
| 99 | + // | ||
| 100 | + // Send NOTIFICATION and close the connection | ||
| 101 | + ChannelBuffer txMessage = | ||
| 102 | + bgpSession.prepareBgpNotificationBadMessageLength(length); | ||
| 103 | + ctx.getChannel().write(txMessage); | ||
| 104 | + bgpSession.closeChannel(ctx); | ||
| 105 | + return null; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + // | ||
| 109 | + // Test whether the rest of the message is received: | ||
| 110 | + // So far we have read the Marker (16 octets) and the | ||
| 111 | + // Length (2 octets) fields. | ||
| 112 | + // | ||
| 113 | + int remainingMessageLen = | ||
| 114 | + length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2; | ||
| 115 | + if (buf.readableBytes() < remainingMessageLen) { | ||
| 116 | + // No enough data received | ||
| 117 | + buf.resetReaderIndex(); | ||
| 118 | + return null; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + // | ||
| 122 | + // Read the BGP message Type field, and process based on that type | ||
| 123 | + // | ||
| 124 | + int type = buf.readUnsignedByte(); | ||
| 125 | + remainingMessageLen--; // Adjust after reading the type | ||
| 126 | + ChannelBuffer message = buf.readBytes(remainingMessageLen); | ||
| 127 | + | ||
| 128 | + // | ||
| 129 | + // Process the remaining of the message based on the message type | ||
| 130 | + // | ||
| 131 | + switch (type) { | ||
| 132 | + case BgpConstants.BGP_TYPE_OPEN: | ||
| 133 | + bgpSession.processBgpOpen(ctx, message); | ||
| 134 | + break; | ||
| 135 | + case BgpConstants.BGP_TYPE_UPDATE: | ||
| 136 | + bgpSession.processBgpUpdate(ctx, message); | ||
| 137 | + break; | ||
| 138 | + case BgpConstants.BGP_TYPE_NOTIFICATION: | ||
| 139 | + bgpSession.processBgpNotification(ctx, message); | ||
| 140 | + break; | ||
| 141 | + case BgpConstants.BGP_TYPE_KEEPALIVE: | ||
| 142 | + bgpSession.processBgpKeepalive(ctx, message); | ||
| 143 | + break; | ||
| 144 | + default: | ||
| 145 | + // | ||
| 146 | + // ERROR: Bad Message Type | ||
| 147 | + // | ||
| 148 | + // Send NOTIFICATION and close the connection | ||
| 149 | + int errorCode = MessageHeaderError.ERROR_CODE; | ||
| 150 | + int errorSubcode = MessageHeaderError.BAD_MESSAGE_TYPE; | ||
| 151 | + ChannelBuffer data = ChannelBuffers.buffer(1); | ||
| 152 | + data.writeByte(type); | ||
| 153 | + ChannelBuffer txMessage = | ||
| 154 | + bgpSession.prepareBgpNotification(errorCode, errorSubcode, | ||
| 155 | + data); | ||
| 156 | + ctx.getChannel().write(txMessage); | ||
| 157 | + bgpSession.closeChannel(ctx); | ||
| 158 | + return null; | ||
| 159 | + } | ||
| 160 | + return null; | ||
| 161 | + } | ||
| 162 | +} |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
| ... | @@ -2,13 +2,15 @@ package org.onlab.packet; | ... | @@ -2,13 +2,15 @@ package org.onlab.packet; |
| 2 | 2 | ||
| 3 | import java.util.Arrays; | 3 | import java.util.Arrays; |
| 4 | 4 | ||
| 5 | + | ||
| 6 | + | ||
| 5 | /** | 7 | /** |
| 6 | * A class representing an IPv4 address. | 8 | * A class representing an IPv4 address. |
| 7 | * <p/> | 9 | * <p/> |
| 8 | * TODO this class is a clone of IpPrefix and still needs to be modified to | 10 | * TODO this class is a clone of IpPrefix and still needs to be modified to |
| 9 | * look more like an IpAddress. | 11 | * look more like an IpAddress. |
| 10 | */ | 12 | */ |
| 11 | -public final class IpAddress { | 13 | +public final class IpAddress implements Comparable<IpAddress> { |
| 12 | 14 | ||
| 13 | // TODO a comparator for netmasks? E.g. for sorting by prefix match order. | 15 | // TODO a comparator for netmasks? E.g. for sorting by prefix match order. |
| 14 | 16 | ||
| ... | @@ -289,6 +291,13 @@ public final class IpAddress { | ... | @@ -289,6 +291,13 @@ public final class IpAddress { |
| 289 | } | 291 | } |
| 290 | 292 | ||
| 291 | @Override | 293 | @Override |
| 294 | + public int compareTo(IpAddress o) { | ||
| 295 | + Long lv = ((long) this.toRealInt()) & 0xffffffffL; | ||
| 296 | + Long rv = ((long) o.toRealInt()) & 0xffffffffL; | ||
| 297 | + return lv.compareTo(rv); | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + @Override | ||
| 292 | public int hashCode() { | 301 | public int hashCode() { |
| 293 | final int prime = 31; | 302 | final int prime = 31; |
| 294 | int result = 1; | 303 | int result = 1; | ... | ... |
-
Please register or login to post a comment