Add BGP-LS Performance Metrics support 33/78833/2
authorodd22 <olivier.dugeon@orange.com>
Mon, 17 Dec 2018 10:37:20 +0000 (11:37 +0100)
committerodd22 <olivier.dugeon@orange.com>
Wed, 19 Dec 2018 17:38:57 +0000 (18:38 +0100)
Allow BGP-LS to handle Performance Metrics as per draft "BGP-LS Advertisement
of IGP Traffic Engineering Performance Metric Extensions"
https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17

 - Add new entries in bgp-linkstate.yang
 - Add description, reference and units to delay and loss typedef
 - Add new parser in LinkAttributesParser.java
 - Add corresponding tests in LinkstateAttributeParserTest.java

JIRA: BGPCEP-855

Change-Id: I0b8cb1f34ede8675d33fcdc746b93d613ce8c484
Signed-off-by: odd22 <olivier.dugeon@orange.com>
bgp/extensions/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/impl/attribute/LinkAttributesParser.java
bgp/extensions/linkstate/src/main/yang/bgp-linkstate.yang
bgp/extensions/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParserTest.java

index 185ecd50dd1b8e1b2366e7a8778333017187c9e7..8169845bc729f7aa961564f2c7d6a5b832e8c111 100644 (file)
@@ -25,11 +25,15 @@ import org.opendaylight.protocol.util.Ipv6Util;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.AdministrativeGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.Delay;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.Ipv4RouterIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.Ipv6RouterIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.LinkProtectionType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.Loss;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.MplsProtocolMask;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.ProtocolId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.LinkMinMaxDelay;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.LinkMinMaxDelayBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.PeerAdjSid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.PeerAdjSidBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.PeerNodeSid;
@@ -85,6 +89,14 @@ public final class LinkAttributesParser {
     private static final int PEER_NODE_SID_CODE = 1101;
     private static final int PEER_ADJ_SID_CODE = 1102;
     private static final int PEER_SET_SID_CODE = 1103;
+    // Performance Metrics
+    private static final int LINK_DELAY = 1114;
+    private static final int LINK_MIN_MAX_DELAY = 1115;
+    private static final int DELAY_VARIATION = 1116;
+    private static final int LINK_LOSS = 1117;
+    private static final int RESIDUAL_BANDWIDTH = 1118;
+    private static final int AVAILABLE_BANDWIDTH = 1119;
+    private static final int UTILIZED_BANDWIDTH = 1120;
 
     private LinkAttributesParser() {
         throw new UnsupportedOperationException();
@@ -191,6 +203,36 @@ public final class LinkAttributesParser {
                 peerSetSids.add(new PeerSetSidsBuilder(SrLinkAttributesParser.parseEpeAdjacencySegmentIdentifier(value)).build());
                 LOG.debug("Parsed Peer Set Sid :{}", peerSetSids.get(peerSetSids.size() - 1));
                 break;
+            // Performance Metrics
+            case LINK_DELAY:
+                builder.setLinkDelay(new Delay(value.readUnsignedInt()));
+                LOG.debug("Parsed Link Delay {}", builder.getLinkDelay());
+                break;
+            case LINK_MIN_MAX_DELAY:
+                builder.setLinkMinMaxDelay(new LinkMinMaxDelayBuilder().setMinDelay(new Delay(value.readUnsignedInt()))
+                        .setMaxDelay(new Delay(value.readUnsignedInt())).build());
+                LOG.debug("Parsed Link Min/Max Delay {}", builder.getLinkMinMaxDelay());
+                break;
+            case DELAY_VARIATION:
+                builder.setDelayVariation(new Delay(value.readUnsignedInt()));
+                LOG.debug("Parsed Delay Variation {}", builder.getDelayVariation());
+                break;
+            case LINK_LOSS:
+                builder.setLinkLoss(new Loss(value.readUnsignedInt()));
+                LOG.debug("Parsed Link Loss {}", builder.getLinkLoss());
+                break;
+            case RESIDUAL_BANDWIDTH:
+                builder.setResidualBandwidth(new Bandwidth(ByteArray.readAllBytes(value)));
+                LOG.debug("Parsed Residual Bandwidth {}", builder.getResidualBandwidth());
+                break;
+            case AVAILABLE_BANDWIDTH:
+                builder.setAvailableBandwidth(new Bandwidth(ByteArray.readAllBytes(value)));
+                LOG.debug("Parsed Available Bandwidth {}", builder.getAvailableBandwidth());
+                break;
+            case UTILIZED_BANDWIDTH:
+                builder.setUtilizedBandwidth(new Bandwidth(ByteArray.readAllBytes(value)));
+                LOG.debug("Parsed Utilized Bandwidth {}", builder.getUtilizedBandwidth());
+                break;
             default:
                 LOG.warn("TLV {} is not a valid link attribute, ignoring it", key);
             }
@@ -256,6 +298,14 @@ public final class LinkAttributesParser {
         ifPresentApply(linkAttributes.getPeerNodeSid(), value -> TlvUtil.writeTLV(PEER_NODE_SID_CODE, SrLinkAttributesParser.serializeAdjacencySegmentIdentifier((PeerNodeSid) value), output));
         ifPresentApply(linkAttributes.getPeerAdjSid(), value -> TlvUtil.writeTLV(PEER_ADJ_SID_CODE, SrLinkAttributesParser.serializeAdjacencySegmentIdentifier((PeerAdjSid) value), output));
         ifPresentApply(linkAttributes.getPeerSetSids(), value -> SrLinkAttributesParser.serializeAdjacencySegmentIdentifiers((List<PeerSetSids>) value, PEER_SET_SID_CODE, output));
+        // Performance Metrics
+        ifPresentApply(linkAttributes.getLinkDelay(), value -> TlvUtil.writeTLV(LINK_DELAY, Unpooled.copyInt((((Delay) value).getValue()).intValue()), output));
+        serializeLinkMinMaxDelay(linkAttributes.getLinkMinMaxDelay(), output);
+        ifPresentApply(linkAttributes.getDelayVariation(), value -> TlvUtil.writeTLV(DELAY_VARIATION, Unpooled.copyInt((((Delay) value).getValue()).intValue()), output));
+        ifPresentApply(linkAttributes.getLinkLoss(), value -> TlvUtil.writeTLV(LINK_LOSS, Unpooled.copyInt((((Loss) value).getValue()).intValue()), output));
+        ifPresentApply(linkAttributes.getResidualBandwidth(), value -> TlvUtil.writeTLV(RESIDUAL_BANDWIDTH, Unpooled.wrappedBuffer(((Bandwidth) value).getValue()), output));
+        ifPresentApply(linkAttributes.getAvailableBandwidth(), value -> TlvUtil.writeTLV(AVAILABLE_BANDWIDTH, Unpooled.wrappedBuffer(((Bandwidth) value).getValue()), output));
+        ifPresentApply(linkAttributes.getUtilizedBandwidth(), value -> TlvUtil.writeTLV(UTILIZED_BANDWIDTH, Unpooled.wrappedBuffer(((Bandwidth) value).getValue()), output));
         LOG.trace("Finished serializing Link Attributes");
     }
 
@@ -290,4 +340,13 @@ public final class LinkAttributesParser {
             TlvUtil.writeTLV(MPLS_PROTOCOL, mplsProtocolMaskBuf, byteAggregator);
         }
     }
+
+    private static void serializeLinkMinMaxDelay(final LinkMinMaxDelay linkMinMaxDelay, final ByteBuf byteAggregator) {
+        if (linkMinMaxDelay != null) {
+            final ByteBuf linkMinMaxDelayBuf = Unpooled.buffer();
+            linkMinMaxDelayBuf.writeInt(linkMinMaxDelay.getMinDelay().getValue().intValue());
+            linkMinMaxDelayBuf.writeInt(linkMinMaxDelay.getMaxDelay().getValue().intValue());
+            TlvUtil.writeTLV(LINK_MIN_MAX_DELAY, linkMinMaxDelayBuf, byteAggregator);
+        }
+    }
 }
index 287f5727453bb9904dd1c0941ec6a2833a986320..6da03f12df5ea59ae08b49615740fd9b3fcbfd9f 100644 (file)
@@ -21,7 +21,7 @@ module bgp-linkstate {
     description
         "This module contains the base data model of a BGP message.
         It rolls up the definitions contained in RFC4271
-        and draft-ietf-idr-ls-distribution-03.
+        and RFC7752.
 
         Copyright (c)2013 Cisco Systems, Inc. All rights reserved.
 
@@ -31,7 +31,9 @@ module bgp-linkstate {
         http://www.eclipse.org/legal/epl-v10.html";
 
     revision "2018-03-29" {
-        description "Add support for add-path for all afi/safi.";
+        description "Add support for add-path for all afi/safi.
+            and Updated to include Performance Metric Extensions";
+        reference "draft-ietf-idr-te-pm-bgp-17";
     }
 
     revision "2017-12-07" {
@@ -83,12 +85,12 @@ module bgp-linkstate {
             }
             enum ipv4-te-lsp {
                 status deprecated;
-                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-4.1";
+                reference "http://tools.ietf.org/html/rfc7752#section-4.1";
                 value 5;
             }
             enum ipv6-te-lsp {
                 status deprecated;
-                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-4.1";
+                reference "http://tools.ietf.org/html/rfc7752#section-4.1";
                 value 6;
             }
         }
@@ -121,12 +123,12 @@ module bgp-linkstate {
             }
             enum rsvp-te {
                 status deprecated;
-                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-2.1";
+                reference "http://tools.ietf.org/html/rfc7752#section-2.1";
                 value 8; // rsvp-te protocol-id TBD by IANA
             }
             enum segment-routing {
                 status deprecated;
-                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-2.1";
+                reference "http://tools.ietf.org/html/rfc7752#section-2.1";
                 value 9; // segment-routing protocol-id TBD by IANA
             }
         }
@@ -508,7 +510,7 @@ module bgp-linkstate {
 
     // linkstate
     typedef mpls-protocol-mask {
-        reference "http://tools.ietf.org/html/draft-ietf-idr-ls-distribution-03#section-3.3.2.2";
+        reference "http://tools.ietf.org/html/rfc7752#section-3.3.2.2";
         type bits {
             bit ldp {
                 position 0;
@@ -534,8 +536,34 @@ module bgp-linkstate {
         }
     }
 
+    typedef delay {
+        description "This 24-bit typedef describes delay over a configurable
+            interval in microseconds, encoded as an integer value. When set to
+            the maximum value 16,777,215 (16.777215 sec), then the delay is at
+            least that value, and it may be larger.";
+        reference "https://tools.ietf.org/html/rfc7471#section-4.1.5";
+        type uint32 {
+            range "0..16777215";
+        }
+        units microseconds;
+    }
+
+    typedef loss {
+        description "This 24-bit typedef describes packet loss as a percentage
+            of the total traffic sent over a configurable interval. The basic
+            unit is 0.000003%, where (2^24 - 2) is 50.331642%. This value is
+            the highest packet loss percentage that can be expressed.
+            Therefore, measured values that are larger than the field maximum
+            SHOULD be encoded as the maximum value.";
+        reference "https://tools.ietf.org/html/rfc7471#section-4.4.5";
+        type uint32 {
+            range "0..16777215";
+        }
+        units percent;
+    }
+
     grouping linkstate-attribute {
-        reference "http://tools.ietf.org/html/draft-ietf-idr-ls-distribution-03#section-3.3.2";
+        reference "http://tools.ietf.org/html/rfc7752#section-3.3.2";
         leaf local-ipv4-router-id {
             type ipv4-router-identifier;
         }
@@ -600,6 +628,47 @@ module bgp-linkstate {
             reference "https://tools.ietf.org/html/draft-ietf-idr-bgpls-segment-routing-epe-05#section-4.3";
             uses bgp-sr:epe-adj-sid-tlv;
         }
+        // Performance Metric https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2
+        leaf link-delay {
+            description "Unidirectional Link Delay";
+            reference "https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2.1";
+            type delay;
+        }
+        container link-min-max-delay {
+            description "Min/Max Unidirectional Link Delay";
+            reference "https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2.2";
+            leaf min-delay {
+                type delay;
+            }
+            leaf max-delay {
+                type delay;
+            }
+        }
+        leaf delay-variation {
+            description "Unidirectional Delay Variation";
+            reference "https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2.3";
+            type delay;
+        }
+        leaf link-loss {
+            description "Unidirectional Link Loss";
+            reference "https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2.4";
+            type loss;
+        }
+        leaf residual-bandwidth {
+            description "Unidirectional Residual Bandwidth";
+            reference "https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2.5";
+            type netc:bandwidth;
+        }
+        leaf available-bandwidth {
+            description "Unidirectional Available Bandwidth";
+            reference "https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2.6";
+            type netc:bandwidth;
+        }
+        leaf utilized-bandwidth {
+            description "Unidirectional Utilized Bandwidth";
+            reference "https://tools.ietf.org/html/draft-ietf-idr-te-pm-bgp-17#section-2.7";
+            type netc:bandwidth;
+        }
     }
 
     typedef route-tag {
@@ -692,7 +761,7 @@ module bgp-linkstate {
             case te-lsp-attributes-case {
                 status deprecated;
                 description "LSP Object";
-                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-2.2";
+                reference "http://tools.ietf.org/html/rfc7752#section-2.2";
                 container te-lsp-attributes {
                     uses rsvp:tspec-object;
                     uses rsvp:flow-spec-object;
index 638ef0d314536ad5617ddc686618bf0384f6ef77..08f4e7ef0e6283ad88e63d84cf8c2b359e913304 100644 (file)
@@ -105,6 +105,14 @@ public class LinkstateAttributeParserTest {
         0x04, 0x4d, 0, 0x08, 0, 0x05, 0, 0, 0x0a, 0x0b, 0x0c, 0x0d, // peer-node-sid
         0x04, 0x4e, 0, 0x08, 0, 0x05, 0, 0, 0x0a, 0x0b, 0x0c, 0x0f, // peer-adj-sid
         0x04, 0x4f, 0, 0x08, 0, 0x05, 0, 0, 0x0a, 0x0b, 0x0c, 0x0e, // peer-set-sid
+        // Performace Metrics
+        0x04, 0x5a, 0, 0x04, 0, 0, 0x27, 0x10, // Link Delay
+        0x04, 0x5b, 0, 0x08, 0, 0, 0x13, (byte)0x88, 0, 0, 0x4e, 0x20, // Link Min-Max Delay
+        0x04, 0x5c, 0, 0x04, 0, 0, 0x27, 0x10, // Link Delay Variation
+        0x04, 0x5d, 0, 0x04, 0, 0, 0, 0, // Link Loss
+        0x04, 0x5e, 0, 0x04, 0x46, 0x43, 0x50, 0, // Residual Bandwidth
+        0x04, 0x5f, 0, 0x04, 0x46, 0x43, 0x50, 0, // Available Bandwidth
+        0x04, 0x60, 0, 0x04, 0, 0, 0, 0,  // Utilized Bandwidth
         0x04, (byte) 0x88, 0, 0x01, 0x0a };
 
     private static final byte[] NODE_ATTR = { 0x01, 0x07, 0, 0x04, 0, 0x2a, 0, 0x2b, 0x04, 0, 0, 0x01, (byte) 0xbc, 0x04, 0x02, 0,
@@ -237,10 +245,24 @@ public class LinkstateAttributeParserTest {
         assertEquals(new Long(168496143L), ((SidCase) ls.getPeerAdjSid().getSidLabelIndex()).getSid());
         assertEquals(new Short("5"), ls.getPeerAdjSid().getWeight().getValue());
 
+        // Performance Metrics
+        assertEquals(new Long(10000L), ls.getLinkDelay().getValue());
+        assertEquals(new Long(5000L), ls.getLinkMinMaxDelay().getMinDelay().getValue());
+        assertEquals(new Long(20000L), ls.getLinkMinMaxDelay().getMaxDelay().getValue());
+        assertEquals(new Long(10000L), ls.getDelayVariation().getValue());
+        assertEquals(new Long(0L), ls.getLinkLoss().getValue());
+        assertArrayEquals(new byte[] { (byte) 0x46, (byte) 0x43, (byte) 0x50, (byte) 0x00 },
+                ls.getResidualBandwidth().getValue());
+        assertArrayEquals(new byte[] { (byte) 0x46, (byte) 0x43, (byte) 0x50, (byte) 0x00 },
+                ls.getAvailableBandwidth().getValue());
+        assertArrayEquals(new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 },
+                ls.getUtilizedBandwidth().getValue());
+
         //serialization
         final ByteBuf buff = Unpooled.buffer();
         this.parser.serializeAttribute(builder.build(), buff);
-        buff.skipBytes(3);
+        // The LINK_ATTR buffer is now greater than 255 bytes. Need to skip one more byte
+        buff.skipBytes(4);
         // there is unresolved TLV at the end, that needs to be cut off
 
         assertArrayEquals(ByteArray.subByte(LINK_ATTR, 0, LINK_ATTR.length -5), ByteArray.getAllBytes(buff));