5 An extension to a protocol means adding parsers and serializers for new elements, such as messages, objects, TLVs or subobjects.
6 This is necessary when you are extending the protocol with another RFC or draft. Both BGP and PCEP parsers are pluggable and you can specify which extensions to load alongside to the base parser in the configuration file.
8 Writing an extension to PCE protocol
9 Current standards support
10 Current pcep base-parser implementation supports following RFCs: +
12 http://tools.ietf.org/html/rfc5440[RFC5440] - Path Computation Element (PCE) Communication Protocol (PCEP) +
13 http://tools.ietf.org/html/rfc5541[RFC5541] - Encoding of Objective Functions in the Path Computation Element Communication Protocol (PCEP) +
14 http://tools.ietf.org/html/rfc5455[RFC5455] - Diffserv-Aware Class-Type Object for the Path Computation Element Communication Protocol +
15 http://tools.ietf.org/html/rfc5521[RFC5521] - Extensions to the Path Computation Element Communication Protocol (PCEP) for Route Exclusions +
16 http://tools.ietf.org/html/rfc5557[RFC5557] - Path Computation Element Communication Protocol (PCEP) Requirements and Protocol Extensions in Support of Global Concurrent Optimization +
18 There are already two extensions for: +
19 https://tools.ietf.org/html/draft-ietf-pce-stateful-pce-09[draft-ietf-pce-stateful-pce] - in versions 02 and 07 +
20 https://tools.ietf.org/html/draft-ietf-pce-pce-initiated-lsp-01[draft-ietf-pce-pce-initiated-lsp] - versions crabbe-initiated-00 and ietf-initiated-00
26 <groupId>${project.groupId}</groupId>
27 <artifactId>pcep-ietf-stateful02</artifactId>
33 <groupId>${project.groupId}</groupId>
34 <artifactId>pcep-ietf-stateful07</artifactId>
37 NOTE: It is important to load the extensions with compatible versions because that they extend each other. In this case crabbe-initiated-00 is compatible with stateful-02 and ietf-initiated-00 is compatible with stateful-07.
39 === Implementing an Extension to PCEP
41 To implement an extension of PCEP: +
43 . Create a separate artefact (eclipse project) for your extension. +
44 Ensure the dependency on pcep-api and pcep-spi.
45 . Write YANG model for new elements or augment existing ones.
46 . Perform `mvn install` to generate files from the model.
47 . Write parsers and serializers. All parsers need to implement *Parser and *Serializer interfaces from pcep-spi, (For example: If you are writing a new TLV, your parser must implement TlvParser and TlvSerializer), add Activator, that extends AbstractPCEPExtensionProviderActivator, where you register your parsers and serializers.
49 === Update Configuration
50 Update [32-pcep.xml]. Register your parser as a module in pcep-impl: +
54 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:impl">
55 prefix:pcep-parser-new-parser
57 <name>pcep-parser-new-parser</name>
60 * Add it as an extension to pcep-parser-base:
64 <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
67 <name>pcep-parser-new-parser</name>
70 * Add the instance to services:
74 <name>pcep-parser-new-parser</name>
75 <provider>/config/modules/module[name='pcep-parser-new-parser']/instance[name='pcep-parser-new-parser']</provider>
78 * Update `odl-pcep-impl-cfg.yang` so that it generates Module and ModuleFactory classes for your new parser.
81 identity pcep-parser-new-parser {
82 base config:module-type;
83 config:provided-service spi:extension;
84 config:java-name-prefix NewParserPCEPParser;
89 augment "/config:modules/config:module/config:configuration" {
90 case pcep-parser-new-parser {
91 when "/config:modules/config:module/config:type = 'pcep-parser-new-parser'";
95 Run mvn install on pcep-impl-config to generate Module and ModuleFactory files.
96 * Update Module to start your NewParserPCEPParserModule.java whent it's created
100 public java.lang.AutoCloseable createInstance() {
101 return new InitiatedActivator();
104 ==== Writing an Extension to BGP +
106 Current standards support
108 Current bgp base-parser implementation supports following RFCs: +
110 http://tools.ietf.org/html/rfc4271[RFC4271] - A Border Gateway Protocol 4 (BGP-4) +
111 http://tools.ietf.org/html/rfc4724[RFC4724] - Graceful Restart Mechanism for BGP +
112 http://tools.ietf.org/html/rfc4760[RFC4760] - Multiprotocol Extensions for BGP-4 +
113 http://tools.ietf.org/html/rfc1997[RFC1997] - BGP Communities Attribute +
114 http://tools.ietf.org/html/rfc4360[RFC4360] - BGP Extended Communities Attribute +
115 http://tools.ietf.org/html/rfc6793[RFC6793] - BGP Support for Four-Octet Autonomous System (AS) Number Space (NEW speaker only) +
117 There is already one extension for: +
118 https://tools.ietf.org/html/draft-ietf-idr-ls-distribution-06[draft-ietf-idr-ls-distribution] - in version 04
120 === Implementing an Extension to BGP
122 To implement an extension to BGP:
124 . Create a separate artefact (eclipse project) for your extension.
125 Ensure it depends on pcep-api and pcep-spi.
126 . Write yang model for new elements or augment existing ones.
127 . Perform `mvn install` to generate files from the model.
128 . Write parsers and serializers. All parsers need to implement *Parser* and *Serializer* interfaces from bgp-spi. For example: If you are writing a new capability, your parser should implement CapabilityParser and CapabilitySerializer).
129 Add Activator, that extends AbstractBGPExtensionProviderActivator, where you register your parsers and serializers. If your extension adds another AFI/SAFI you must to add another Activator that extends AbstractRIBExtensionProviderActivator and registrate new address family and subsequent address family.
131 === Updating Configuration
132 Update 31-bgp.xml. Register your parser as a module in bgp-impl:
136 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:new-parser">
137 prefix:bgp-new-parser
139 <name>bgp-new-parser</name>
142 * Add it as an extension to bgp-parser-base:
145 <type xmlns:bgpspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi">
148 <name>bgp-new-parser</name>
151 * Add the instance to services:
154 <name>bgp-new-parser</name>
155 <provider>/modules/module[type='bgp-new-parser'][name='bgp-new-parser']</provider>
158 Also, if you are introducing new AFI/SAFI, do not forget to registrate your extension also to RIB.
160 * Create your own configuration file so that it generates Module and ModuleFactory classes for your new parser.
163 identity bgp-new-parser {
164 base config:module-type;
165 config:provided-service bgpspi:extension;
166 config:provided-service ribspi:extension; // for new AFI/SAFI
167 config:java-name-prefix NewParser;
171 augment "/config:modules/config:module/config:configuration" {
172 case bgp-new-parser {
173 when "/config:modules/config:module/config:type = 'bgp-new-parser'";
177 Run mvn install on your extension artefact to generate Module and ModuleFactory files.
179 * Update Module to start your NewParserModule.java whent it's created.
182 public java.lang.AutoCloseable createInstance() {
183 return new NewParserActivator();
187 ==== Programmatic Interface(s)
189 Howto pull code from gerrit: https://wiki.opendaylight.org/view/OpenDaylight_Controller:Pulling,_Hacking,_and_Pushing_the_Code_from_the_CLI[OpenDaylight Controller:Pulling, Hacking, and Pushing the Code from the CLI] +
190 Gerrit repository: https://git.opendaylight.org/gerrit/bgpcep[gerrit] +
191 Bugzilla: https://bugs.opendaylight.org/[Bugzilla] +
194 * bgpcep-bugs@opendaylight.org
195 * bgpcep-dev@opendaylight.org
197 YANG Models - https://jenkins.opendaylight.org/bgpcep/job/bgpcep-nightly/lastSuccessfulBuild/artifact/target/staging/releasepom/apidocs/index.html[BGP LS PCEP:Models] +
199 API Documentation – https://wiki.opendaylight.org/view/BGP_LS_PCEP:Models[Javadoc API]
201 For debugging purposes, set lower log levels for bgpcep project in logback.xml.
204 <logger name="org.opendaylight.protocol" level="TRACE" />
205 <logger name="org.opendaylight.bgpcep" level="TRACE" />
208 ==== Vendor Specific Constraints in PCEP
209 http://tools.ietf.org/html/draft-ietf-pce-rfc7150bis-00[draft-ietf-pce-rfc7150bis-00] - Conveying Vendor-Specific Constraints in the Path Computation Element communication Protocol.
211 Draft defines new PCEP object - Vendor Information object, that can be used to carry arbitrary, proprietary information such as vendor-specific constraints. Draft also defines new PCEP TLV - Vendor Information TLV that can be used to carry arbitrary information within any PCEP object that supports TLVs.
213 The ODL PCEP supports _draft-ietf-pce-rfc7150bis-00_ and provides abstraction for developers to create vendor-specific TLVs/objects extensions. The yang model of _vendor-information-tlv/object_ is defined in _pcep-types.yang_ and used in pcep objects/messages as defined in the draft.
215 This tutorial shows how to develop PCEP extension of vendor-information object and TLV for fictional company named My Vendor, whose enterprise number is 0. A result will be OSGi bundle and initial configuration xml file, that supports MY-VENDOR-TLV and MY-VENDOR-OBJECT in ODL.
217 * First, create simple maven module named _pcep-my-vendor_. For simplification assume the module parent is _pcep_ maven project. For bundle packaging add _plugin maven-bundle-plugin_ into _pom.xml_ and also _yang-maven-plugin_ for compile-time java code generating.
220 <artifactId>pcep-my-vendor</artifactId>
221 <description>PCEP MY VENDOR EXTENSION</description>
222 <packaging>bundle</packaging>
223 <name>${project.artifactId}</name>
227 <groupId>org.apache.felix</groupId>
228 <artifactId>maven-bundle-plugin</artifactId>
229 <extensions>true</extensions>
232 <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
237 <groupId>org.opendaylight.yangtools</groupId>
238 <artifactId>yang-maven-plugin</artifactId>
243 * Add required dependencies into _pom.xml_.
248 <groupId>org.opendaylight.controller</groupId>
249 <artifactId>config-api</artifactId>
252 <groupId>${project.groupId}</groupId>
253 <artifactId>pcep-api</artifactId>
256 <groupId>${project.groupId}</groupId>
257 <artifactId>pcep-spi</artifactId>
260 <groupId>${project.groupId}</groupId>
261 <artifactId>pcep-impl</artifactId>
265 === Vendor Information TLV
267 The Vendor Information TLV is used for vendor-specific information that applies to a specific PCEP object by including the TLV in the object. For the purpose of this tutorial, define MY-VENDOR-TLV, which can be loaded wih just simple unsigned 32-bit integer (4 bytes) as it's value and the TLV is carried in Open object.
271 * Initial step is to extend pcep-types and pcep-message yang models, augmentation target is _enterprise-specific-information_ (choice) located in Open messages's Open object. Create yang file (_pcep-my-vendor.yang_), in project's _src/main/yang_ folder, with definition of the vendor information and required augmentations.
272 * Now build project with maven, after that generated Java API's appears in _target/generated-sources/sal_.
275 grouping my-vendor-information {
280 augment "/msg:open/msg:open-message/msg:open/msg:tlvs/msg:vendor-information-tlv/msg:enterprise-specific-information" {
282 when "enterprise-number = 0";
283 uses my-vendor-information;
287 * Vendor Information TLV parser/serializer
288 * Next step is an implementation of the enterprise-specific-information (TLV's value) parser/serializer. It is simple serialization/deserialization of unsigned integer (long type in Java representation), other functionality is already presented in _org.opendaylight.protocol.pcep.impl.tlv.AbstractVendorInformationTlvParser abstract_ class. Create class extending _AbstractVendorInformationTlvParser_ and implement missing methods.
292 public class MyVendorInformationTlvParser extends AbstractVendorInformationTlvParser {
293 private static final EnterpriseNumber EN = new EnterpriseNumber(0L);
295 public EnterpriseNumber getEnterpriseNumber() {
299 public EnterpriseSpecificInformation parseEnterpriseSpecificInformation(final ByteBuf buffer)
300 throws PCEPDeserializerException {
301 return new MyVendorBuilder().setPayload(buffer.readUnsignedInt()).build();
304 public void serializeEnterpriseSpecificInformation(final EnterpriseSpecificInformation esi, final ByteBuf buffer) {
305 final MyVendor myVendorInfo = (MyVendor) esi;
306 buffer.writeInt(myVendorInfo.getPayload().intValue());
310 *Vendor Information TLV Activator* +
312 * Now, parser/serializer needs to be registered to _VendorInformationTlvRegistry_. Create class extending _AbstractPCEPExtensionProviderActivator_ and implement _startImpl_ method - register parser idenfied by enterprise number and register serializer identified by the class extending _EnterpriseSpecificInformation_.
316 public class Activator extends AbstractPCEPExtensionProviderActivator {
318 protected List<AutoCloseable> startImpl(PCEPExtensionProviderContext context) {
319 final List<AutoCloseable> regs = new ArrayList<>();
320 final MyVendorInformationTlvParser parser = new MyVendorInformationTlvParser();
321 regs.add(context.registerVendorInformationTlvParser(parser.getEnterpriseNumber(), parser));
322 regs.add(context.registerVendorInformationTlvSerializer(MyVendor.class, parser));
327 *Configuration Module* +
329 * Create configuration yang module with name i.e. _pcep-my-vendor-cfg.yang_. Define My Vendor parser extension service provider config module.
330 * Build project with maven to generate cofiguration module and module factory. They are located in _src/main/java_.
331 * Implement _MyVendorPCEPParserModule#createInstance()_ - return instance of Activator created above.
334 identity pcep-parser-my-vendor {
335 base config:module-type;
336 config:provided-service spi:extension;
337 config:java-name-prefix MyVendorPCEPParser;
339 augment "/config:modules/config:module/config:configuration" {
340 case pcep-parser-my-vendor {
341 when "/config:modules/config:module/config:type = 'pcep-parser-my-vendor'";
347 public java.lang.AutoCloseable createInstance() {
348 return new Activator();
351 *Initial Configuration* +
353 Create initial configuration xml file, where module _pcep-parser-my-vendor_ is instantiated and injected into the _global-pcep-extensions_.
357 <required-capabilities>
358 <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:spi?module=odl-pcep-spi-cfg&revision=2013-11-15</capability>
359 <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg?module=pcep-my-vendor-cfg&revision=2014-09-20</capability>
360 </required-capabilities>
362 <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
363 <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
365 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">prefix:pcep-extensions-impl</type>
366 <name>global-pcep-extensions</name>
368 <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
371 <name>pcep-parser-my-vendor</name>
375 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg">
376 prefix:pcep-parser-my-vendor
378 <name>pcep-parser-my-vendor</name>
381 <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
383 <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
387 <name>pcep-parser-my-vendor</name>
388 <provider>/config/modules/module[name='pcep-parser-my-vendor']/instance[name='pcep-parser-my-vendor']</provider>
397 === Vendor Information Object
399 For the tutorial purposes, define MY-VENDOR-OBJECT, which can be loaded with Ipv4 address (4 bytes) as it's value and the object is carried in PCRep message's response.
403 * Initial step is to extend _pcep-types_ and _pcep-message_ yang models, augmentation target is _enterprise-specific-information_ (choice) located in PCRep messages. Create yang file (_pcep-my-vendor.yang_), in project _src/main/yang_ folder, with definition of the vendor information and required augmentations.
404 * Now build project with maven, after that generated Java API's appears in _target/generated-sources/sal_.
407 grouping my-vendor-information {
409 type inet:ipv4-address;
412 augment "/msg:pcrep/msg:pcrep-message/msg:replies/msg:vendor-information-object/msg:enterprise-specific-information" {
414 when "enterprise-number = 0";
415 uses my-vendor-information;
419 *Vendor Information Object Parser/Serializer* +
421 * Implementation of the _enterprise-sepecific-information_ (Object value) parser/serializer. It is simple serialization/deserialization of IPv4 address, other functionality is already presented in _org.opendaylight.protocol.pcep.impl.object.AbstractVendorInformationObjectParser_ abstract class. Create class extending _AbstractVendorInformationObjectParser_ and implement missing methods.
425 public class MyVendorInformationObjectParser extends AbstractVendorInformationObjectParser {
426 private static final EnterpriseNumber EN = new EnterpriseNumber(0L);
428 public EnterpriseNumber getEnterpriseNumber() {
432 public EnterpriseSpecificInformation parseEnterpriseSpecificInformation(final ByteBuf buffer)
433 throws PCEPDeserializerException {
434 return new MyVendorBuilder().setPayload(Ipv4Util.addressForByteBuf(buffer)).build();
437 public void serializeEnterpriseSpecificInformation(final EnterpriseSpecificInformation esi, final ByteBuf buffer) {
438 final MyVendor myVendor = (MyVendor) esi;
439 buffer.writeBytes(Ipv4Util.bytesForAddress(myVendor.getPayload()));
443 *Vendor Information Object Activator* +
445 Parser/serializer must be registered to VendorInformationObjectRegistry. Create class extending AbstractPCEPExtensionProviderActivator and implement startImpl method - register parser idenfied by enterprise number and register serializer identified by the class extending EnterpriseSpecificInformation.
448 public class Activator extends AbstractPCEPExtensionProviderActivator {
450 protected List<AutoCloseable> startImpl(PCEPExtensionProviderContext context) {
451 final List<AutoCloseable> regs = new ArrayList<>();
452 final MyVendorInformationObjectParser parser = new MyVendorInformationObjectParser();
453 regs.add(context.registerVendorInformationObjectParser(parser.getEnterpriseNumber(), parser));
454 regs.add(context.registerVendorInformationObjectSerializer(MyVendor.class, parser));
459 *Configuration Module* +
461 * Create configuration yang module with name (_pcep-my-vendor-cfg.yang_).
462 * Define My Vendor parser extension service provider configuration module.
463 * Build project with maven to generate configuration module and module factory located in _src/main/java_.
464 * Implement _MyVendorPCEPParserModule#createInstance()_ - return instance of Activator created.
467 identity pcep-parser-my-vendor {
468 base config:module-type;
469 config:provided-service spi:extension;
470 config:java-name-prefix MyVendorPCEPParser;
473 augment "/config:modules/config:module/config:configuration" {
474 case pcep-parser-my-vendor {
475 when "/config:modules/config:module/config:type = 'pcep-parser-my-vendor'";
481 public java.lang.AutoCloseable createInstance() {
482 return new Activator();
486 *Initial Configuration* +
488 Create initial configuration xml file, where module _pcep-parser-my-vendor_ is instantiated and injected into the _global-pcep-extensions_.
492 <required-capabilities>
493 <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:spi?module=odl-pcep-spi-cfg&revision=2013-11-15</capability>
494 <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg?module=pcep-my-vendor-cfg&revision=2014-09-20</capability>
495 </required-capabilities>
497 <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
498 <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
500 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
501 prefix:pcep-extensions-impl
503 <name>global-pcep-extensions</name>
505 <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
508 <name>pcep-parser-my-vendor</name>
512 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg">
513 prefix:pcep-parser-my-vendor
515 <name>pcep-parser-my-vendor</name>
518 <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
520 <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
524 <name>pcep-parser-my-vendor</name>
525 <provider>/config/modules/module[name='pcep-parser-my-vendor']/instance[name='pcep-parser-my-vendor']</provider>