Kunihiro Ishiguro

4 Octet AS Path Capability is sent to neighbor.

4 Octet AS in AS_PATH is parsed.
Now BGP can establish 4 Octet AS Path enabled peering with neighbor.

Change-Id: Ibb72e8037554928584ccafe6a14b82ffaca7e2cd
...@@ -227,6 +227,12 @@ public final class BgpConstants { ...@@ -227,6 +227,12 @@ public final class BgpConstants {
227 /** BGP UPDATE Attributes Type Code AS_PATH. */ 227 /** BGP UPDATE Attributes Type Code AS_PATH. */
228 public static final int TYPE = 2; 228 public static final int TYPE = 2;
229 229
230 + /** BGP AS length. */
231 + public static final int AS_LENGTH = 2;
232 +
233 + /** BGP 4 Octet AS length (RFC 6793). */
234 + public static final int AS_4OCTET_LENGTH = 4;
235 +
230 /** BGP UPDATE AS_PATH Type: AS_SET. */ 236 /** BGP UPDATE AS_PATH Type: AS_SET. */
231 public static final int AS_SET = 1; 237 public static final int AS_SET = 1;
232 238
......
...@@ -23,6 +23,7 @@ import org.onosproject.sdnip.bgp.BgpConstants.Notifications; ...@@ -23,6 +23,7 @@ import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
23 import org.onosproject.sdnip.bgp.BgpConstants.Notifications.OpenMessageError; 23 import org.onosproject.sdnip.bgp.BgpConstants.Notifications.OpenMessageError;
24 import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities; 24 import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities;
25 import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions; 25 import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions;
26 +import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.As4Octet;
26 import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException; 27 import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException;
27 import org.slf4j.Logger; 28 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory; 29 import org.slf4j.LoggerFactory;
...@@ -334,8 +335,14 @@ final class BgpOpen { ...@@ -334,8 +335,14 @@ final class BgpOpen {
334 throw new BgpParseException(errorMsg); 335 throw new BgpParseException(errorMsg);
335 } 336 }
336 long as4Number = message.readUnsignedInt(); 337 long as4Number = message.readUnsignedInt();
337 - // TODO: Implement support for 4-octet AS Numbers 338 +
339 + bgpSession.setRemoteAs4OctetCapability();
338 bgpSession.setRemoteAs4Octet(as4Number); 340 bgpSession.setRemoteAs4Octet(as4Number);
341 +
342 + // Copy remote 4-octet AS Number Capabilities and AS Number.
343 + // This is temporary setting until local AS number configuration is supported.
344 + bgpSession.setLocalAs4OctetCapability();
345 + bgpSession.setRemoteAs(as4Number);
339 log.debug("BGP RX OPEN Capability: AS4 Number = {}", 346 log.debug("BGP RX OPEN Capability: AS4 Number = {}",
340 as4Number); 347 as4Number);
341 break; 348 break;
...@@ -420,6 +427,15 @@ final class BgpOpen { ...@@ -420,6 +427,15 @@ final class BgpOpen {
420 message.writeByte(MultiprotocolExtensions.SAFI_MULTICAST); 427 message.writeByte(MultiprotocolExtensions.SAFI_MULTICAST);
421 } 428 }
422 429
430 + // 4 octet AS path capability
431 + if (bgpSession.getLocalAs4OctetCapability()) {
432 + message.writeByte(Capabilities.TYPE); // Param type
433 + message.writeByte(Capabilities.MIN_LENGTH +
434 + As4Octet.LENGTH); // Param len
435 + message.writeByte(As4Octet.CODE); // Capab, code
436 + message.writeByte(As4Octet.LENGTH); // Capab, len
437 + message.writeInt((int) bgpSession.getLocalAs());
438 + }
423 return message; 439 return message;
424 } 440 }
425 } 441 }
......
...@@ -66,6 +66,7 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -66,6 +66,7 @@ public class BgpSession extends SimpleChannelHandler {
66 private boolean remoteIpv4Multicast; // Peer IPv4/MULTICAST AFI/SAFI 66 private boolean remoteIpv4Multicast; // Peer IPv4/MULTICAST AFI/SAFI
67 private boolean remoteIpv6Unicast; // Peer IPv6/UNICAST AFI/SAFI 67 private boolean remoteIpv6Unicast; // Peer IPv6/UNICAST AFI/SAFI
68 private boolean remoteIpv6Multicast; // Peer IPv6/MULTICAST AFI/SAFI 68 private boolean remoteIpv6Multicast; // Peer IPv6/MULTICAST AFI/SAFI
69 + private boolean remoteAs4OctetCapability; // Peer 4 octet AS path capability
69 // 70 //
70 private SocketAddress localAddress; // Local IP addr/port 71 private SocketAddress localAddress; // Local IP addr/port
71 private Ip4Address localIp4Address; // Local IPv4 address 72 private Ip4Address localIp4Address; // Local IPv4 address
...@@ -77,6 +78,7 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -77,6 +78,7 @@ public class BgpSession extends SimpleChannelHandler {
77 private boolean localIpv4Multicast; // Local IPv4/MULTICAST AFI/SAFI 78 private boolean localIpv4Multicast; // Local IPv4/MULTICAST AFI/SAFI
78 private boolean localIpv6Unicast; // Local IPv6/UNICAST AFI/SAFI 79 private boolean localIpv6Unicast; // Local IPv6/UNICAST AFI/SAFI
79 private boolean localIpv6Multicast; // Local IPv6/MULTICAST AFI/SAFI 80 private boolean localIpv6Multicast; // Local IPv6/MULTICAST AFI/SAFI
81 + private boolean localAs4OctetCapability; // Local 4 octet AS path capability
80 // 82 //
81 private long localKeepaliveInterval; // Keepalive interval 83 private long localKeepaliveInterval; // Keepalive interval
82 84
...@@ -188,7 +190,7 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -188,7 +190,7 @@ public class BgpSession extends SimpleChannelHandler {
188 // In the future the local AS number should be configured as part 190 // In the future the local AS number should be configured as part
189 // of an explicit BGP peering configuration. 191 // of an explicit BGP peering configuration.
190 // 192 //
191 - this.localAs = remoteAs; 193 + setLocalAs(remoteAs);
192 } 194 }
193 195
194 /** 196 /**
...@@ -330,6 +332,47 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -330,6 +332,47 @@ public class BgpSession extends SimpleChannelHandler {
330 } 332 }
331 333
332 /** 334 /**
335 + * Gets the BGP session remote 4 octet AS path capability.
336 + *
337 + * @return true when the BGP session remote has 4 octet AS path capability
338 + */
339 + public boolean getRemoteAs4OctetCapability() {
340 + return remoteAs4OctetCapability;
341 + }
342 +
343 + /**
344 + * Sets the BGP session remote 4 octet AS path capability.
345 + */
346 + void setRemoteAs4OctetCapability() {
347 + this.remoteAs4OctetCapability = true;
348 + }
349 +
350 + /**
351 + * Gets the BGP session local 4 octet AS path capability.
352 + *
353 + * @return true when the BGP session local has 4 octet AS path capability
354 + */
355 + public boolean getLocalAs4OctetCapability() {
356 + return localAs4OctetCapability;
357 + }
358 +
359 + /**
360 + * Sets the BGP session local 4 octet AS path capability.
361 + */
362 + void setLocalAs4OctetCapability() {
363 + this.localAs4OctetCapability = true;
364 + }
365 +
366 + /**
367 + * Gets the BGP session 4 octet AS path capability.
368 + *
369 + * @return true when the BGP session is 4 octet AS path capable
370 + */
371 + public boolean isAs4OctetCapable() {
372 + return getRemoteAs4OctetCapability() && getLocalAs4OctetCapability();
373 + }
374 +
375 + /**
333 * Gets the BGP session local address. 376 * Gets the BGP session local address.
334 * 377 *
335 * @return the BGP session local address 378 * @return the BGP session local address
...@@ -366,6 +409,15 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -366,6 +409,15 @@ public class BgpSession extends SimpleChannelHandler {
366 } 409 }
367 410
368 /** 411 /**
412 + * Sets the BGP session local AS number.
413 + *
414 + * @param localAs the BGP session local AS number to set
415 + */
416 + public void setLocalAs(long localAs) {
417 + this.localAs = localAs;
418 + }
419 +
420 + /**
369 * Gets the BGP session local Holdtime. 421 * Gets the BGP session local Holdtime.
370 * 422 *
371 * @return the BGP session local Holdtime 423 * @return the BGP session local Holdtime
......
...@@ -26,6 +26,7 @@ import org.jboss.netty.buffer.ChannelBuffers; ...@@ -26,6 +26,7 @@ import org.jboss.netty.buffer.ChannelBuffers;
26 import org.jboss.netty.channel.ChannelHandlerContext; 26 import org.jboss.netty.channel.ChannelHandlerContext;
27 import org.onlab.packet.Ip4Address; 27 import org.onlab.packet.Ip4Address;
28 import org.onlab.packet.Ip4Prefix; 28 import org.onlab.packet.Ip4Prefix;
29 +import org.onosproject.sdnip.bgp.BgpConstants.Update.AsPath;
29 import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError; 30 import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError;
30 import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException; 31 import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException;
31 import org.slf4j.Logger; 32 import org.slf4j.Logger;
...@@ -610,17 +611,30 @@ final class BgpUpdate { ...@@ -610,17 +611,30 @@ final class BgpUpdate {
610 throw new BgpParseException(errorMsg); 611 throw new BgpParseException(errorMsg);
611 } 612 }
612 613
614 + // 4-octet AS number handling.
615 + int asPathLen;
616 + if (bgpSession.isAs4OctetCapable()) {
617 + asPathLen = AsPath.AS_4OCTET_LENGTH;
618 + } else {
619 + asPathLen = AsPath.AS_LENGTH;
620 + }
621 +
613 // Parse the AS numbers 622 // Parse the AS numbers
614 - if (2 * pathSegmentLength > attrLen) { 623 + if (asPathLen * pathSegmentLength > attrLen) {
615 // ERROR: Malformed AS_PATH 624 // ERROR: Malformed AS_PATH
616 actionsBgpUpdateMalformedAsPath(bgpSession, ctx); 625 actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
617 String errorMsg = "Malformed AS Path"; 626 String errorMsg = "Malformed AS Path";
618 throw new BgpParseException(errorMsg); 627 throw new BgpParseException(errorMsg);
619 } 628 }
620 - attrLen -= (2 * pathSegmentLength); 629 + attrLen -= (asPathLen * pathSegmentLength);
621 ArrayList<Long> segmentAsNumbers = new ArrayList<>(); 630 ArrayList<Long> segmentAsNumbers = new ArrayList<>();
622 while (pathSegmentLength-- > 0) { 631 while (pathSegmentLength-- > 0) {
623 - long asNumber = message.readUnsignedShort(); 632 + long asNumber;
633 + if (asPathLen == AsPath.AS_4OCTET_LENGTH) {
634 + asNumber = message.readUnsignedInt();
635 + } else {
636 + asNumber = message.readUnsignedShort();
637 + }
624 segmentAsNumbers.add(asNumber); 638 segmentAsNumbers.add(asNumber);
625 } 639 }
626 640
......
...@@ -48,6 +48,8 @@ public class BgpNeighborsListCommand extends AbstractShellCommand { ...@@ -48,6 +48,8 @@ public class BgpNeighborsListCommand extends AbstractShellCommand {
48 " Local router ID %s, IP %s, BGP version %d, Hold time %d"; 48 " Local router ID %s, IP %s, BGP version %d, Hold time %d";
49 private static final String FORMAT_NEIGHBOR_LINE5 = 49 private static final String FORMAT_NEIGHBOR_LINE5 =
50 " Local AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s"; 50 " Local AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s";
51 + private static final String FORMAT_NEIGHBOR_LINE6 =
52 + " 4 Octet AS Capability: %s %s";
51 53
52 @Override 54 @Override
53 protected void execute() { 55 protected void execute() {
...@@ -120,6 +122,11 @@ public class BgpNeighborsListCommand extends AbstractShellCommand { ...@@ -120,6 +122,11 @@ public class BgpNeighborsListCommand extends AbstractShellCommand {
120 bgpSession.getLocalIpv4Multicast() ? "YES" : "NO", 122 bgpSession.getLocalIpv4Multicast() ? "YES" : "NO",
121 bgpSession.getLocalIpv6Unicast() ? "YES" : "NO", 123 bgpSession.getLocalIpv6Unicast() ? "YES" : "NO",
122 bgpSession.getLocalIpv6Multicast() ? "YES" : "NO"); 124 bgpSession.getLocalIpv6Multicast() ? "YES" : "NO");
125 + if (bgpSession.getLocalAs4OctetCapability() || bgpSession.getRemoteAs4OctetCapability()) {
126 + print(FORMAT_NEIGHBOR_LINE6,
127 + bgpSession.getLocalAs4OctetCapability() ? "Advertised" : "",
128 + bgpSession.getRemoteAs4OctetCapability() ? "Received" : "");
129 + }
123 } 130 }
124 131
125 /** 132 /**
......