Pingping Lin
Committed by Gerrit Code Review

[ONOS-2939] Let sdn-ip also can parse bird's bgp OPEN message

RFC5492 allows multiple Capability triples per Optional Parameter.
But our code only support parsing 1 Capability triple per Optional Parameter.
It works with Quagga, but failed parsing bird OPEN message.
This patch adds support for multiple Capability triples per Optional Parameter.

Change-Id: Iae6295d608e44676a44ef6a0ae1868d8dcd7648d
...@@ -309,94 +309,104 @@ final class BgpOpen { ...@@ -309,94 +309,104 @@ final class BgpOpen {
309 case BgpConstants.Open.Capabilities.TYPE: 309 case BgpConstants.Open.Capabilities.TYPE:
310 // Optional Parameter Type: Capabilities 310 // Optional Parameter Type: Capabilities
311 if (paramLen < BgpConstants.Open.Capabilities.MIN_LENGTH) { 311 if (paramLen < BgpConstants.Open.Capabilities.MIN_LENGTH) {
312 - // ERROR: Malformed Capability 312 + // ERROR: Malformed Param Type
313 - String errorMsg = "Malformed Capability Type " + paramType; 313 + String errorMsg = "Malformed Capabilities Optional "
314 + + "Parameter Type " + paramType;
314 throw new BgpMessage.BgpParseException(errorMsg); 315 throw new BgpMessage.BgpParseException(errorMsg);
315 } 316 }
316 - int capabEnd = message.readerIndex() + paramLen; 317 + int paramEnd = message.readerIndex() + paramLen;
317 - int capabCode = message.readUnsignedByte(); 318 + // Parse Capabilities
318 - int capabLen = message.readUnsignedByte(); 319 + while (message.readerIndex() < paramEnd) {
319 - if (message.readerIndex() + capabLen > capabEnd) { 320 + if (paramEnd - message.readerIndex() <
320 - // ERROR: Malformed Capability 321 + BgpConstants.Open.Capabilities.MIN_LENGTH) {
321 - String errorMsg = "Malformed Capability Type " + paramType; 322 + String errorMsg = "Malformed Capabilities";
322 - throw new BgpMessage.BgpParseException(errorMsg);
323 - }
324 -
325 - switch (capabCode) {
326 - case BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE:
327 - // Multiprotocol Extensions Capabilities (RFC 4760)
328 - if (capabLen != BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH) {
329 - // ERROR: Multiprotocol Extension Length Error
330 - String errorMsg = "Multiprotocol Extension Length Error";
331 throw new BgpMessage.BgpParseException(errorMsg); 323 throw new BgpMessage.BgpParseException(errorMsg);
332 } 324 }
333 - // Decode the AFI (2 octets) and SAFI (1 octet) 325 + int capabCode = message.readUnsignedByte();
334 - int afi = message.readUnsignedShort(); 326 + int capabLen = message.readUnsignedByte();
335 - int reserved = message.readUnsignedByte(); 327 + if (message.readerIndex() + capabLen > paramEnd) {
336 - int safi = message.readUnsignedByte(); 328 + // ERROR: Malformed Capability
337 - log.debug("BGP RX OPEN Capability: AFI = {} SAFI = {}", 329 + String errorMsg = "Malformed Capability instance with "
338 - afi, safi); 330 + + "code " + capabCode;
339 - // 331 + throw new BgpMessage.BgpParseException(errorMsg);
340 - // Setup the AFI/SAFI in the BgpSession
341 - //
342 - // NOTE: For now we just copy the remote AFI/SAFI setting
343 - // to the local configuration.
344 - //
345 - if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
346 - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
347 - bgpSession.remoteInfo().setIpv4Unicast();
348 - bgpSession.localInfo().setIpv4Unicast();
349 - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
350 - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
351 - bgpSession.remoteInfo().setIpv4Multicast();
352 - bgpSession.localInfo().setIpv4Multicast();
353 - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
354 - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
355 - bgpSession.remoteInfo().setIpv6Unicast();
356 - bgpSession.localInfo().setIpv6Unicast();
357 - } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
358 - safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
359 - bgpSession.remoteInfo().setIpv6Multicast();
360 - bgpSession.localInfo().setIpv6Multicast();
361 - } else {
362 - log.debug("BGP RX OPEN Capability: Unknown AFI = {} SAFI = {}",
363 - afi, safi);
364 } 332 }
365 - break;
366 333
367 - case BgpConstants.Open.Capabilities.As4Octet.CODE: 334 + switch (capabCode) {
368 - // Support for 4-octet AS Number Capabilities (RFC 6793) 335 + case BgpConstants.Open.Capabilities.MultiprotocolExtensions.CODE:
369 - if (capabLen != BgpConstants.Open.Capabilities.As4Octet.LENGTH) { 336 + // Multiprotocol Extensions Capabilities (RFC 4760)
370 - // ERROR: 4-octet AS Number Capability Length Error 337 + if (capabLen != BgpConstants.Open.Capabilities.MultiprotocolExtensions.LENGTH) {
371 - String errorMsg = "4-octet AS Number Capability Length Error"; 338 + // ERROR: Multiprotocol Extension Length Error
372 - throw new BgpMessage.BgpParseException(errorMsg); 339 + String errorMsg = "Multiprotocol Extension Length Error";
340 + throw new BgpMessage.BgpParseException(errorMsg);
341 + }
342 + // Decode the AFI (2 octets) and SAFI (1 octet)
343 + int afi = message.readUnsignedShort();
344 + int reserved = message.readUnsignedByte();
345 + int safi = message.readUnsignedByte();
346 + log.debug("BGP RX OPEN Capability: AFI = {} SAFI = {}",
347 + afi, safi);
348 + //
349 + // Setup the AFI/SAFI in the BgpSession
350 + //
351 + // NOTE: For now we just copy the remote AFI/SAFI setting
352 + // to the local configuration.
353 + //
354 + if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
355 + safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
356 + bgpSession.remoteInfo().setIpv4Unicast();
357 + bgpSession.localInfo().setIpv4Unicast();
358 + } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4 &&
359 + safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
360 + bgpSession.remoteInfo().setIpv4Multicast();
361 + bgpSession.localInfo().setIpv4Multicast();
362 + } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
363 + safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST) {
364 + bgpSession.remoteInfo().setIpv6Unicast();
365 + bgpSession.localInfo().setIpv6Unicast();
366 + } else if (afi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV6 &&
367 + safi == BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_MULTICAST) {
368 + bgpSession.remoteInfo().setIpv6Multicast();
369 + bgpSession.localInfo().setIpv6Multicast();
370 + } else {
371 + log.debug("BGP RX OPEN Capability: Unknown AFI = {} SAFI = {}",
372 + afi, safi);
373 + }
374 + break;
375 +
376 + case BgpConstants.Open.Capabilities.As4Octet.CODE:
377 + // Support for 4-octet AS Number Capabilities (RFC 6793)
378 + if (capabLen != BgpConstants.Open.Capabilities.As4Octet.LENGTH) {
379 + // ERROR: 4-octet AS Number Capability Length Error
380 + String errorMsg = "4-octet AS Number Capability Length Error";
381 + throw new BgpMessage.BgpParseException(errorMsg);
382 + }
383 + long as4Number = message.readUnsignedInt();
384 +
385 + bgpSession.remoteInfo().setAs4OctetCapability();
386 + bgpSession.remoteInfo().setAs4Number(as4Number);
387 +
388 + //
389 + // Copy remote 4-octet AS Number Capabilities and AS
390 + // Number. This is a temporary setting until local AS
391 + // number configuration is supported.
392 + //
393 + bgpSession.localInfo().setAs4OctetCapability();
394 + bgpSession.localInfo().setAs4Number(as4Number);
395 + log.debug("BGP RX OPEN Capability: AS4 Number = {}",
396 + as4Number);
397 + break;
398 +
399 + default:
400 + // Unknown Capability: ignore it
401 + log.debug("BGP RX OPEN Capability Code = {} Length = {}",
402 + capabCode, capabLen);
403 + message.readBytes(capabLen);
404 + break;
373 } 405 }
374 - long as4Number = message.readUnsignedInt();
375 -
376 - bgpSession.remoteInfo().setAs4OctetCapability();
377 - bgpSession.remoteInfo().setAs4Number(as4Number);
378 -
379 - //
380 - // Copy remote 4-octet AS Number Capabilities and AS
381 - // Number. This is a temporary setting until local AS
382 - // number configuration is supported.
383 - //
384 - bgpSession.localInfo().setAs4OctetCapability();
385 - bgpSession.localInfo().setAs4Number(as4Number);
386 - log.debug("BGP RX OPEN Capability: AS4 Number = {}",
387 - as4Number);
388 - break;
389 -
390 - default:
391 - // Unknown Capability: ignore it
392 - log.debug("BGP RX OPEN Capability Code = {} Length = {}",
393 - capabCode, capabLen);
394 - message.readBytes(capabLen);
395 - break;
396 - }
397 406
398 - break;
399 407
408 + }
409 + break;
400 default: 410 default:
401 // Unknown Parameter Type: ignore it 411 // Unknown Parameter Type: ignore it
402 log.debug("BGP RX OPEN Parameter Type = {} Length = {}", 412 log.debug("BGP RX OPEN Parameter Type = {} Length = {}",
......