1 package org.opendaylight.protocol.bgp.parser.impl.message.update;
5 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
6 import org.opendaylight.protocol.bgp.parser.BGPError;
7 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
8 import org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSegmentParser.SegmentType;
9 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
10 import org.opendaylight.protocol.util.ByteArray;
11 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AsPath;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AsPathBuilder;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.as.path.Segments;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.as.path.SegmentsBuilder;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.CAListBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.CASetBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.c.a.list.AsSequence;
21 import com.google.common.collect.Lists;
22 import com.google.common.primitives.UnsignedBytes;
24 final class AsPathAttributeParser implements AttributeParser {
25 static final int TYPE = 2;
28 * Parses AS_PATH from bytes.
30 * @param bytes byte array to be parsed
31 * @return new ASPath object
32 * @throws BGPDocumentedException if there is no AS_SEQUENCE present (mandatory)
33 * @throws BGPParsingException
35 private static AsPath parseAsPath(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
37 final List<Segments> ases = Lists.newArrayList();
38 boolean isSequence = false;
39 while (byteOffset < bytes.length) {
40 final int type = UnsignedBytes.toInt(bytes[byteOffset]);
41 final SegmentType segmentType = AsPathSegmentParser.parseType(type);
42 if (segmentType == null) {
43 throw new BGPParsingException("AS Path segment type unknown : " + type);
45 byteOffset += AsPathSegmentParser.TYPE_LENGTH;
47 final int count = UnsignedBytes.toInt(bytes[byteOffset]);
48 byteOffset += AsPathSegmentParser.LENGTH_SIZE;
50 if (segmentType == SegmentType.AS_SEQUENCE) {
51 final List<AsSequence> numbers = AsPathSegmentParser.parseAsSequence(count,
52 ByteArray.subByte(bytes, byteOffset, count * AsPathSegmentParser.AS_NUMBER_LENGTH));
53 ases.add(new SegmentsBuilder().setCSegment(new CAListBuilder().setAsSequence(numbers).build()).build());
56 final List<AsNumber> list = AsPathSegmentParser.parseAsSet(count,
57 ByteArray.subByte(bytes, byteOffset, count * AsPathSegmentParser.AS_NUMBER_LENGTH));
58 ases.add(new SegmentsBuilder().setCSegment(new CASetBuilder().setAsSet(list).build()).build());
61 byteOffset += count * AsPathSegmentParser.AS_NUMBER_LENGTH;
64 if (!isSequence && bytes.length != 0) {
65 throw new BGPDocumentedException("AS_SEQUENCE must be present in AS_PATH attribute.", BGPError.AS_PATH_MALFORMED);
67 return new AsPathBuilder().setSegments(ases).build();
71 public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException, BGPParsingException {
72 builder.setAsPath(parseAsPath(bytes));