Merge "Bump models to match draft-clemm-netmod-yang-network-topo-01"
[bgpcep.git] / bgp / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / LinkstateNlriParser.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.bgp.linkstate;
9
10 import java.math.BigInteger;
11 import java.util.Arrays;
12
13 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
14 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
15 import org.opendaylight.protocol.bgp.parser.spi.NlriUtil;
16 import org.opendaylight.protocol.concepts.Ipv4Util;
17 import org.opendaylight.protocol.concepts.Ipv6Util;
18 import org.opendaylight.protocol.util.ByteArray;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.AreaIdentifier;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.DomainIdentifier;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Identifier;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv4InterfaceIdentifier;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv6InterfaceIdentifier;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NlriType;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NodeIdentifier;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.OspfInterfaceIdentifier;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.OspfRouteType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.ProtocolId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.RouteDistinguisher;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.TopologyIdentifier;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifier;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifierBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestination;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestinationBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptors;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptorsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptors;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptorsBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptors;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptorsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.RemoteNodeDescriptors;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.CRouterIdentifier;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisNodeBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisPseudonodeBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfNodeBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfPseudonodeBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.node.IsisNodeBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.pseudonode.IsisPseudonodeBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.node.OspfNodeBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.pseudonode.OspfPseudonodeBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.DestinationType;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlriBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.IsoSystemIdentifier;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63 import com.google.common.primitives.UnsignedBytes;
64
65 public final class LinkstateNlriParser implements NlriParser {
66         private static final Logger logger = LoggerFactory.getLogger(LinkstateNlriParser.class);
67         private static final int ROUTE_DISTINGUISHER_LENGTH = 8;
68         private static final int PROTOCOL_ID_LENGTH = 1;
69         private static final int IDENTIFIER_LENGTH = 8;
70
71         private static final int TYPE_LENGTH = 2;
72         private static final int LENGTH_SIZE = 2;
73
74         private final boolean isVpn;
75
76         public LinkstateNlriParser(final boolean isVpn) {
77                 this.isVpn = isVpn;
78         }
79
80         private static NodeIdentifier parseLink(final CLinkstateDestinationBuilder builder, final byte[] bytes) throws BGPParsingException {
81                 int byteOffset = 0;
82                 final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
83                 byteOffset += TYPE_LENGTH;
84                 final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
85                 byteOffset += LENGTH_SIZE;
86                 final NodeIdentifier remote = null;
87                 if (type == 257) {
88                         builder.setRemoteNodeDescriptors((RemoteNodeDescriptors) parseNodeDescriptors(ByteArray.subByte(bytes, byteOffset, length)));
89                         byteOffset += length;
90                 }
91                 builder.setLinkDescriptors(parseLinkDescriptors(ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset)));
92                 return remote;
93         }
94
95         private static LinkDescriptors parseLinkDescriptors(final byte[] bytes) throws BGPParsingException {
96                 int byteOffset = 0;
97                 final LinkDescriptorsBuilder builder = new LinkDescriptorsBuilder();
98                 while (byteOffset != bytes.length) {
99                         final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
100                         byteOffset += TYPE_LENGTH;
101                         final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
102                         byteOffset += LENGTH_SIZE;
103                         final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
104                         logger.debug("Parsing Link Descriptor: {}", Arrays.toString(value));
105                         switch (type) {
106                         case 258:
107                                 builder.setLinkLocalIdentifier(ByteArray.subByte(value, 0, 4));
108                                 builder.setLinkRemoteIdentifier(ByteArray.subByte(value, 4, 4));
109                                 logger.trace("Parsed link local {} remote {} Identifiers.", builder.getLinkLocalIdentifier(),
110                                                 builder.getLinkRemoteIdentifier());
111                                 break;
112                         case 259:
113                                 final Ipv4InterfaceIdentifier lipv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
114                                 builder.setIpv4InterfaceAddress(lipv4);
115                                 logger.trace("Parsed IPv4 interface address {}.", lipv4);
116                                 break;
117                         case 260:
118                                 final Ipv4InterfaceIdentifier ripv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
119                                 builder.setIpv4NeighborAddress(ripv4);
120                                 logger.trace("Parsed IPv4 neighbor address {}.", ripv4);
121                                 break;
122                         case 261:
123                                 final Ipv6InterfaceIdentifier lipv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
124                                 builder.setIpv6InterfaceAddress(lipv6);
125                                 logger.trace("Parsed IPv6 interface address {}.", lipv6);
126                                 break;
127                         case 262:
128                                 final Ipv6InterfaceIdentifier ripv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
129                                 builder.setIpv6NeighborAddress(ripv6);
130                                 logger.trace("Parsed IPv6 neighbor address {}.", ripv6);
131                                 break;
132                         case 263:
133                                 final TopologyIdentifier topId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
134                                 builder.setMultiTopologyId(topId);
135                                 logger.trace("Parsed topology identifier {}.", topId);
136                                 break;
137                         default:
138                                 throw new BGPParsingException("Link Descriptor not recognized, type: " + type);
139                         }
140                         byteOffset += length;
141                 }
142                 logger.debug("Finished parsing Link descriptors.");
143                 return builder.build();
144         }
145
146         private static NodeIdentifier parseNodeDescriptors(final byte[] bytes) throws BGPParsingException {
147                 int byteOffset = 0;
148                 AsNumber asnumber = null;
149                 DomainIdentifier bgpId = null;
150                 AreaIdentifier ai = null;
151                 CRouterIdentifier routerId = null;
152                 while (byteOffset != bytes.length) {
153                         final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
154                         byteOffset += TYPE_LENGTH;
155                         final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
156                         byteOffset += LENGTH_SIZE;
157                         final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
158                         logger.debug("Parsing Node Descriptor: {}", Arrays.toString(value));
159                         switch (type) {
160                         case 512:
161                                 asnumber = new AsNumber(ByteArray.bytesToLong(value));
162                                 logger.trace("Parsed AS number {}", asnumber);
163                                 break;
164                         case 513:
165                                 bgpId = new DomainIdentifier(value);
166                                 logger.trace("Parsed bgpId {}", bgpId);
167                                 break;
168                         case 514:
169                                 ai = new AreaIdentifier(value);
170                                 logger.trace("Parsed area identifier {}", ai);
171                                 break;
172                         case 515:
173                                 routerId = parseRouterId(value);
174                                 logger.trace("Parsed Router Identifier {}", routerId);
175                                 break;
176                         default:
177                                 throw new BGPParsingException("Node Descriptor not recognized, type: " + type);
178                         }
179                         byteOffset += length;
180                 }
181                 logger.debug("Finished parsing Node descriptors.");
182                 return new LocalNodeDescriptorsBuilder().setAsNumber(asnumber).setDomainId(bgpId).setAreaId(ai).setCRouterIdentifier(routerId).build();
183         }
184
185         private static CRouterIdentifier parseRouterId(final byte[] value) throws BGPParsingException {
186                 if (value.length == 6) {
187                         return new CIsisNodeBuilder().setIsisNode(
188                                         new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
189                 }
190                 if (value.length == 7) {
191                         if (value[6] == 0) {
192                                 logger.warn("PSN octet is 0. Ignoring System ID.");
193                                 return new CIsisNodeBuilder().setIsisNode(
194                                                 new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
195                         } else {
196                                 final IsIsRouterIdentifier iri = new IsIsRouterIdentifierBuilder().setIsoSystemId(
197                                                 new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build();
198                                 return new CIsisPseudonodeBuilder().setIsisPseudonode(
199                                                 new IsisPseudonodeBuilder().setIsIsRouterIdentifier(iri).setPsn((short) UnsignedBytes.toInt(value[6])).build()).build();
200                         }
201                 }
202                 if (value.length == 4) {
203                         return new COspfNodeBuilder().setOspfNode(new OspfNodeBuilder().setOspfRouterId(ByteArray.subByte(value, 0, 4)).build()).build();
204                 }
205                 if (value.length == 8) {
206                         final byte[] o = ByteArray.subByte(value, 0, 4); // FIXME: OSPFv3 vs OSPFv2
207                         final OspfInterfaceIdentifier a = new OspfInterfaceIdentifier(ByteArray.subByte(value, 4, 4));
208                         return new COspfPseudonodeBuilder().setOspfPseudonode(new OspfPseudonodeBuilder().setOspfRouterId(o).setLanInterface(a).build()).build();
209                 }
210                 throw new BGPParsingException("Router Id of invalid length " + value.length);
211         }
212
213         private static PrefixDescriptors parsePrefixDescriptors(final NodeIdentifier localDescriptor, final byte[] bytes)
214                         throws BGPParsingException {
215                 int byteOffset = 0;
216                 final PrefixDescriptorsBuilder builder = new PrefixDescriptorsBuilder();
217                 while (byteOffset != bytes.length) {
218                         final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
219                         byteOffset += TYPE_LENGTH;
220                         final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
221                         byteOffset += LENGTH_SIZE;
222                         final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
223                         logger.trace("Parsing Prefix Descriptor: {}", Arrays.toString(value));
224                         switch (type) {
225                         case 263:
226                                 final TopologyIdentifier topologyId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
227                                 builder.setMultiTopologyId(topologyId);
228                                 logger.trace("Parsed Topology Identifier: {}", topologyId);
229                                 break;
230                         case 264:
231                                 final int rt = ByteArray.bytesToInt(value);
232                                 final OspfRouteType routeType = OspfRouteType.forValue(rt);
233                                 if (routeType == null) {
234                                         throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
235                                 }
236                                 builder.setOspfRouteType(routeType);
237                                 logger.trace("Parser RouteType: {}", routeType);
238                                 break;
239                         case 265:
240                                 IpPrefix prefix = null;
241                                 final int prefixLength = UnsignedBytes.toInt(value[0]);
242                                 final int size = prefixLength / 8 + ((prefixLength % 8 == 0) ? 0 : 1);
243                                 if (size != value.length - 1) {
244                                         logger.debug("Expected length {}, actual length {}.", size, value.length - 1);
245                                         throw new BGPParsingException("Illegal length of IP reachability TLV: " + (value.length - 1));
246                                 }
247                                 if (size == 4) {
248                                         prefix = new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
249                                 } else {
250                                         prefix = new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
251                                 }
252                                 builder.setIpReachabilityInformation(prefix);
253                                 logger.trace("Parsed IP reachability info: {}", prefix);
254                                 break;
255                         default:
256                                 throw new BGPParsingException("Prefix Descriptor not recognized, type: " + type);
257                         }
258                         byteOffset += length;
259                 }
260                 logger.debug("Finished parsing Prefix descriptors.");
261                 return builder.build();
262         }
263
264         /**
265          * Parses common parts for Link State Nodes, Links and Prefixes, that includes protocol ID and identifier tlv.
266          * 
267          * @param nlri
268          * @return BGPLinkMP or BGPNodeMP
269          * @throws BGPParsingException
270          */
271         private CLinkstateDestination parseNlri(final byte[] nlri) throws BGPParsingException {
272                 if (nlri.length == 0) {
273                         return null;
274                 }
275                 int byteOffset = 0;
276
277                 final CLinkstateDestinationBuilder builder = new CLinkstateDestinationBuilder();
278
279                 while (byteOffset != nlri.length) {
280                         final NlriType type = NlriType.forValue(ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, TYPE_LENGTH)));
281                         builder.setNlriType(type);
282
283                         byteOffset += TYPE_LENGTH;
284                         // length means total length of the tlvs including route distinguisher not including the type field
285                         final int length = ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, LENGTH_SIZE));
286                         byteOffset += LENGTH_SIZE;
287                         RouteDistinguisher distinguisher = null;
288                         if (this.isVpn) {
289                                 // this parses route distinguisher
290                                 distinguisher = new RouteDistinguisher(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(nlri, byteOffset,
291                                                 ROUTE_DISTINGUISHER_LENGTH))));
292                                 builder.setDistinguisher(distinguisher);
293                                 byteOffset += ROUTE_DISTINGUISHER_LENGTH;
294                         }
295                         // parse source protocol
296                         final ProtocolId sp = ProtocolId.forValue(ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, PROTOCOL_ID_LENGTH)));
297                         byteOffset += PROTOCOL_ID_LENGTH;
298                         builder.setProtocolId(sp);
299
300                         // parse identifier
301                         final Identifier identifier = new Identifier(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(nlri, byteOffset,
302                                         IDENTIFIER_LENGTH))));
303                         byteOffset += IDENTIFIER_LENGTH;
304                         builder.setIdentifier(identifier);
305
306                         // if we are dealing with linkstate nodes/links, parse local node descriptor
307                         NodeIdentifier localDescriptor = null;
308                         int locallength = 0;
309                         final int localtype = ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, TYPE_LENGTH));
310                         byteOffset += TYPE_LENGTH;
311                         locallength = ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, LENGTH_SIZE));
312                         byteOffset += LENGTH_SIZE;
313                         if (localtype == 256) {
314                                 localDescriptor = parseNodeDescriptors(ByteArray.subByte(nlri, byteOffset, locallength));
315                         }
316                         byteOffset += locallength;
317                         builder.setLocalNodeDescriptors((LocalNodeDescriptors) localDescriptor);
318                         final int restLength = length - (this.isVpn ? ROUTE_DISTINGUISHER_LENGTH : 0) - PROTOCOL_ID_LENGTH - IDENTIFIER_LENGTH
319                                         - TYPE_LENGTH - LENGTH_SIZE - locallength;
320                         logger.debug("Restlength {}", restLength);
321                         switch (type) {
322                         case Link:
323                                 parseLink(builder, ByteArray.subByte(nlri, byteOffset, restLength));
324                                 break;
325                         case Ipv4Prefix:
326                         case Ipv6Prefix:
327                                 builder.setPrefixDescriptors(parsePrefixDescriptors(localDescriptor, ByteArray.subByte(nlri, byteOffset, restLength)));
328                                 break;
329                         case Node:
330                                 // node nlri is already parsed as it contains only the common fields for node and link nlri
331                                 break;
332                         }
333                         byteOffset += restLength;
334                 }
335                 return builder.build();
336         }
337
338         @Override
339         public void parseNlri(final byte[] nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException {
340                 final CLinkstateDestination dst = parseNlri(nlri);
341
342                 // FIXME: This cast is because of a bug in yangtools (augmented choice has no relationship with base choice)
343                 final DestinationType s = (DestinationType) new DestinationLinkstateBuilder().setCLinkstateDestination(dst).build();
344
345                 builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(s).build());
346         }
347
348         @Override
349         public void parseNlri(final byte[] nlri, final byte[] nextHop, final MpReachNlriBuilder builder) throws BGPParsingException {
350                 final CLinkstateDestination dst = parseNlri(nlri);
351
352                 // FIXME: This cast is because of a bug in yangtools (augmented choice has no relationship with base choice)
353                 final DestinationType s = (DestinationType) new DestinationLinkstateBuilder().setCLinkstateDestination(dst).build();
354
355                 builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(s).build());
356                 NlriUtil.parseNextHop(nextHop, builder);
357         }
358 }