BUG-113: split out attribute parsers 35/1835/7
authorRobert Varga <rovarga@cisco.com>
Fri, 11 Oct 2013 12:57:55 +0000 (14:57 +0200)
committerRobert Varga <rovarga@cisco.com>
Sun, 13 Oct 2013 06:01:09 +0000 (08:01 +0200)
Change-Id: I9d60cbff4e2bcd914b5e4d4ff90fdf21707ff2ac
Signed-off-by: Robert Varga <rovarga@cisco.com>
23 files changed:
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPUpdateMessageParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LinkstateAttributeParser.java [moved from bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LinkStateParser.java with 97% similarity]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/PathAttributeParser.java [deleted file]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/SimpleAttributeRegistry.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/PathAttributeParserTest.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeRegistry.java

index 973774cde79b673c13bd5c347b248d0b60b7e0e8..f4ec7d2803622a688c81064aa04bbe5409b498e0 100644 (file)
@@ -14,7 +14,8 @@ import java.util.List;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.bgp.parser.impl.message.update.PathAttributeParser;
+import org.opendaylight.protocol.bgp.parser.impl.message.update.SimpleAttributeRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ByteArray;
@@ -27,6 +28,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
+
 /**
  * LENGTH fields, that denote the length of the fields with variable length, have fixed SIZE.
  * 
@@ -35,7 +38,7 @@ import org.slf4j.LoggerFactory;
  */
 public class BGPUpdateMessageParser implements MessageParser {
        public static final int TYPE = 2;
-       public static final BGPUpdateMessageParser PARSER = new BGPUpdateMessageParser();
+       public static final BGPUpdateMessageParser PARSER = new BGPUpdateMessageParser(SimpleAttributeRegistry.INSTANCE);
 
        private static Logger logger = LoggerFactory.getLogger(BGPUpdateMessageParser.class);
 
@@ -49,9 +52,11 @@ public class BGPUpdateMessageParser implements MessageParser {
         */
        public static final int TOTAL_PATH_ATTR_LENGTH_SIZE = 2;
 
-       // Constructors -------------------------------------------------------
-       private BGPUpdateMessageParser() {
+       private final AttributeRegistry reg;
 
+       // Constructors -------------------------------------------------------
+       public BGPUpdateMessageParser(final AttributeRegistry reg) {
+               this.reg = Preconditions.checkNotNull(reg);
        }
 
        // Getters & setters --------------------------------------------------
@@ -89,7 +94,7 @@ public class BGPUpdateMessageParser implements MessageParser {
 
                try {
                        if (totalPathAttrLength > 0) {
-                               final PathAttributes pathAttributes = PathAttributeParser.parseAttribute(ByteArray.subByte(body, byteOffset,
+                               final PathAttributes pathAttributes = reg.parseAttributes(ByteArray.subByte(body, byteOffset,
                                                totalPathAttrLength));
                                byteOffset += totalPathAttrLength;
                                eventBuilder.setPathAttributes(pathAttributes);
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java
new file mode 100644 (file)
index 0000000..c768b49
--- /dev/null
@@ -0,0 +1,13 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+final class AS4AggregatorAttributeParser implements AttributeParser {
+       static final int TYPE = 17;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               // AS4 Aggregator is ignored
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java
new file mode 100644 (file)
index 0000000..aeebf24
--- /dev/null
@@ -0,0 +1,13 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+final class AS4PathAttributeParser implements AttributeParser {
+       static final int TYPE = 18;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               // AS4 Path is ignored
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java
new file mode 100644 (file)
index 0000000..92dda87
--- /dev/null
@@ -0,0 +1,32 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.concepts.IPv4;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.Aggregator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AggregatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+final class AggregatorAttributeParser implements AttributeParser {
+       static final int TYPE = 7;
+
+       /**
+        * Parse AGGREGATOR from bytes
+        * 
+        * @param bytes byte array to be parsed
+        * @return {@link Aggregator} BGP Aggregator
+        */
+       private static Aggregator parseAggregator(final byte[] bytes) {
+               final AsNumber asNumber = new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(bytes, 0, AsPathSegmentParser.AS_NUMBER_LENGTH)));
+               final Ipv4Address address = new Ipv4Address(IPv4.FAMILY.addressForBytes(
+                               ByteArray.subByte(bytes, AsPathSegmentParser.AS_NUMBER_LENGTH, 4)).toString());
+               return new AggregatorBuilder().setAsNumber(asNumber).setNetworkAddress(address).build();
+       }
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               builder.setAggregator(parseAggregator(bytes));
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java
new file mode 100644 (file)
index 0000000..e4f8037
--- /dev/null
@@ -0,0 +1,74 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import java.util.List;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPError;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSegmentParser.SegmentType;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AsPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AsPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.as.path.Segments;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.as.path.SegmentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.CAListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.CASetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.c.a.list.AsSequence;
+
+import com.google.common.collect.Lists;
+import com.google.common.primitives.UnsignedBytes;
+
+final class AsPathAttributeParser implements AttributeParser {
+       static final int TYPE = 2;
+
+       /**
+        * Parses AS_PATH from bytes.
+        * 
+        * @param bytes byte array to be parsed
+        * @return new ASPath object
+        * @throws BGPDocumentedException if there is no AS_SEQUENCE present (mandatory)
+        * @throws BGPParsingException
+        */
+       private static AsPath parseAsPath(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
+               int byteOffset = 0;
+               final List<Segments> ases = Lists.newArrayList();
+               boolean isSequence = false;
+               while (byteOffset < bytes.length) {
+                       final int type = UnsignedBytes.toInt(bytes[byteOffset]);
+                       final SegmentType segmentType = AsPathSegmentParser.parseType(type);
+                       if (segmentType == null) {
+                               throw new BGPParsingException("AS Path segment type unknown : " + type);
+                       }
+                       byteOffset += AsPathSegmentParser.TYPE_LENGTH;
+
+                       final int count = UnsignedBytes.toInt(bytes[byteOffset]);
+                       byteOffset += AsPathSegmentParser.LENGTH_SIZE;
+
+                       if (segmentType == SegmentType.AS_SEQUENCE) {
+                               final List<AsSequence> numbers = AsPathSegmentParser.parseAsSequence(count,
+                                               ByteArray.subByte(bytes, byteOffset, count * AsPathSegmentParser.AS_NUMBER_LENGTH));
+                               ases.add(new SegmentsBuilder().setCSegment(new CAListBuilder().setAsSequence(numbers).build()).build());
+                               isSequence = true;
+                       } else {
+                               final List<AsNumber> list = AsPathSegmentParser.parseAsSet(count,
+                                               ByteArray.subByte(bytes, byteOffset, count * AsPathSegmentParser.AS_NUMBER_LENGTH));
+                               ases.add(new SegmentsBuilder().setCSegment(new CASetBuilder().setAsSet(list).build()).build());
+
+                       }
+                       byteOffset += count * AsPathSegmentParser.AS_NUMBER_LENGTH;
+               }
+
+               if (!isSequence && bytes.length != 0) {
+                       throw new BGPDocumentedException("AS_SEQUENCE must be present in AS_PATH attribute.", BGPError.AS_PATH_MALFORMED);
+               }
+               return new AsPathBuilder().setSegments(ases).build();
+       }
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder)     throws BGPDocumentedException, BGPParsingException {
+               builder.setAsPath(parseAsPath(bytes));
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java
new file mode 100644 (file)
index 0000000..67f6707
--- /dev/null
@@ -0,0 +1,14 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AtomicAggregateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+final class AtomicAggregateAttributeParser implements AttributeParser {
+       static final int TYPE = 6;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               builder.setAtomicAggregate(new AtomicAggregateBuilder().build());
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java
new file mode 100644 (file)
index 0000000..62e3baa
--- /dev/null
@@ -0,0 +1,26 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import java.util.List;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
+
+import com.google.common.collect.Lists;
+
+final class ClusterIdAttributeParser implements AttributeParser {
+       static final int TYPE = 10;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               final List<ClusterIdentifier> list = Lists.newArrayList();
+               int i = 0;
+               while (i < bytes.length) {
+                       list.add(new ClusterIdentifier(ByteArray.subByte(bytes, i, 4)));
+                       i += 4;
+               }
+
+               builder.setClusterId(list);
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java
new file mode 100644 (file)
index 0000000..3ed49eb
--- /dev/null
@@ -0,0 +1,27 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import java.util.List;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.Communities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+import com.google.common.collect.Lists;
+
+final class CommunitiesAttributeParser implements AttributeParser {
+       static final int TYPE = 8;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
+               final List<Communities> set = Lists.newArrayList();
+               int i = 0;
+               while (i < bytes.length) {
+                       set.add((Communities) CommunitiesParser.parseCommunity(ByteArray.subByte(bytes, i, CommunitiesParser.COMMUNITY_LENGTH)));
+                       i += CommunitiesParser.COMMUNITY_LENGTH;
+               }
+
+               builder.setCommunities(set);
+       }
+}
\ No newline at end of file
index 9b20326b04983f8ab0ba627a9f0f0f988bcafdd8..999038d96fa0014bc87e282fc698801b92cbf543 100644 (file)
@@ -59,8 +59,9 @@ public class CommunitiesParser {
         * @throws BGPDocumentedException
         */
        static Community parseCommunity(final byte[] bytes) throws BGPDocumentedException {
-               if (bytes.length != COMMUNITY_LENGTH)
+               if (bytes.length != COMMUNITY_LENGTH) {
                        throw new BGPDocumentedException("Community with wrong length: " + bytes.length, BGPError.OPT_ATTR_ERROR);
+               }
                if (Arrays.equals(bytes, new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x01 })) {
                        return CommunityUtil.NO_EXPORT;
                } else if (Arrays.equals(bytes, new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x02 })) {
@@ -91,51 +92,54 @@ public class CommunitiesParser {
                                return new CRouteTargetExtendedCommunityBuilder().setRouteTargetExtendedCommunity(
                                                new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(
                                                                new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
                        } else if (subType == 3) {
                                return new CRouteOriginExtendedCommunityBuilder().setRouteOriginExtendedCommunity(
                                                new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(
                                                                new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
-                       } else
+                                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                       } else {
                                return new CAsSpecificExtendedCommunityBuilder().setAsSpecificExtendedCommunity(
                                                new AsSpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(
                                                                new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                       }
                case 40: // 01000000
                        return new CAsSpecificExtendedCommunityBuilder().setAsSpecificExtendedCommunity(
                                        new AsSpecificExtendedCommunityBuilder().setTransitive(true).setGlobalAdministrator(
                                                        new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                       ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                                                                       ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
                case 2:
                        if (subType == 2) {
                                return new CRouteTargetExtendedCommunityBuilder().setRouteTargetExtendedCommunity(
                                                new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(
                                                                new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
                        } else if (subType == 3) {
                                return new CRouteOriginExtendedCommunityBuilder().setRouteOriginExtendedCommunity(
                                                new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(
                                                                new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
-                       } else
+                                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                       } else {
                                throw new BGPDocumentedException("Could not parse Extended Community subtype: " + subType, BGPError.OPT_ATTR_ERROR);
+                       }
                case 1:
                        if (subType == 2) {
                                return new CRouteTargetExtendedCommunityBuilder().setRouteTargetExtendedCommunity(
                                                new RouteTargetExtendedCommunityBuilder().setGlobalAdministrator(
                                                                new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
                        } else if (subType == 3) {
                                return new CRouteOriginExtendedCommunityBuilder().setRouteOriginExtendedCommunity(
                                                new RouteOriginExtendedCommunityBuilder().setGlobalAdministrator(
                                                                new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(value, 0, AS_NUMBER_LENGTH)))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
-                       } else
+                                                                               ByteArray.subByte(value, AS_NUMBER_LENGTH, AS_LOCAL_ADMIN_LENGTH)).build()).build();
+                       } else {
                                return new CInet4SpecificExtendedCommunityBuilder().setInet4SpecificExtendedCommunity(
                                                new Inet4SpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(
                                                                Ipv4Util.addressForBytes(ByteArray.subByte(value, 0, 4))).setLocalAdministrator(
-                                                               ByteArray.subByte(value, 4, 2)).build()).build();
+                                                                               ByteArray.subByte(value, 4, 2)).build()).build();
+                       }
                case 41: // 01000001
                        return new CInet4SpecificExtendedCommunityBuilder().setInet4SpecificExtendedCommunity(
                                        new Inet4SpecificExtendedCommunityBuilder().setTransitive(true).setGlobalAdministrator(
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java
new file mode 100644 (file)
index 0000000..e928c5c
--- /dev/null
@@ -0,0 +1,28 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import java.util.List;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.ExtendedCommunities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+import com.google.common.collect.Lists;
+
+final class ExtendedCommunitiesAttributeParser implements AttributeParser {
+       static final int TYPE = 16;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
+               final List<ExtendedCommunities> set = Lists.newArrayList();
+               int i = 0;
+               while (i < bytes.length) {
+                       set.add((ExtendedCommunities) CommunitiesParser.parseExtendedCommunity(ByteArray.subByte(bytes, i,
+                                       CommunitiesParser.EXTENDED_COMMUNITY_LENGTH)));
+                       i += CommunitiesParser.EXTENDED_COMMUNITY_LENGTH;
+               }
+
+               builder.setExtendedCommunities(set);
+       }
+}
\ No newline at end of file
similarity index 97%
rename from bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LinkStateParser.java
rename to bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LinkstateAttributeParser.java
index cc1a168b599b417dd4a516e5415c9f9dd553c859..2fdbe0e3bdcbf0eed9b3dfdb63883d3521bb2cb6 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Set;
 
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.impl.ByteList;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.concepts.Ipv6Util;
 import org.opendaylight.protocol.util.ByteArray;
@@ -41,6 +42,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NodeIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.OspfInterfaceIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.OspfRouteType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.PathAttributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.PathAttributes1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.ProtocolId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.RouteDistinguisher;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.RouteTag;
@@ -76,6 +79,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.PrefixAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.PrefixAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Bandwidth;
@@ -96,9 +100,11 @@ import com.google.common.primitives.UnsignedBytes;
  * 
  * @see <a href="http://tools.ietf.org/html/draft-gredler-idr-ls-distribution-01">BGP-LS draft</a>
  */
-public class LinkStateParser {
+public class LinkstateAttributeParser implements AttributeParser {
+       // FIXME: update to IANA number once it is known
+       static final int TYPE = 99;
 
-       private static final Logger logger = LoggerFactory.getLogger(LinkStateParser.class);
+       private static final Logger logger = LoggerFactory.getLogger(LinkstateAttributeParser.class);
 
        private static final int TYPE_LENGTH = 2;
 
@@ -117,7 +123,10 @@ public class LinkStateParser {
 
        private static final Set<Integer> prefixTlvs = Sets.newHashSet(1152, 1153, 1154, 1155, 1156, 1157);
 
-       private LinkStateParser() {
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPParsingException {
+               final PathAttributes1 a = new PathAttributes1Builder().setLinkstatePathAttribute(parseLinkState(bytes)).build();
+               builder.addAugmentation(PathAttributes1.class, a);
        }
 
        /**
@@ -375,8 +384,9 @@ public class LinkStateParser {
                        case 264:
                                final int rt = ByteArray.bytesToInt(value);
                                final OspfRouteType routeType = OspfRouteType.forValue(rt);
-                               if (routeType == null)
+                               if (routeType == null) {
                                        throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
+                               }
                                builder.setOspfRouteType(routeType);
                                logger.trace("Parser RouteType: {}", routeType);
                                break;
@@ -388,10 +398,11 @@ public class LinkStateParser {
                                        logger.debug("Expected length {}, actual length {}.", size, value.length - 1);
                                        throw new BGPParsingException("Illegal length of IP reachability TLV: " + (value.length - 1));
                                }
-                               if (size == 4)
+                               if (size == 4) {
                                        prefix = new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
-                               else
+                               } else {
                                        prefix = new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
+                               }
                                builder.setIpReachabilityInformation(prefix);
                                logger.trace("Parsed IP reachability info: {}", prefix);
                                break;
@@ -494,8 +505,9 @@ public class LinkStateParser {
                                        break;
                                case 1093:
                                        final LinkProtectionType lpt = LinkProtectionType.forValue(UnsignedBytes.toInt(value[0]));
-                                       if (lpt == null)
+                                       if (lpt == null) {
                                                throw new BGPParsingException("Link Protection Type not recognized: " + UnsignedBytes.toInt(value[0]));
+                                       }
                                        builder.setLinkProtection(lpt);
                                        logger.trace("Parsed Link Protection Type {}", lpt);
                                        break;
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java
new file mode 100644 (file)
index 0000000..fe9454f
--- /dev/null
@@ -0,0 +1,15 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.LocalPrefBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+final class LocalPreferenceAttributeParser implements AttributeParser {
+       static final int TYPE = 5;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               builder.setLocalPref(new LocalPrefBuilder().setPref(ByteArray.bytesToLong(bytes)).build());
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java
new file mode 100644 (file)
index 0000000..7a4acc2
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPError;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes1Builder;
+
+final class MPReachAttributeParser implements AttributeParser {
+       static final int TYPE = 14;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
+               try {
+                       final PathAttributes1 a = new PathAttributes1Builder().setMpReachNlri(MPReachParser.parseMPReach(bytes)).build();
+
+                       builder.addAugmentation(PathAttributes1.class, a);
+               } catch (final BGPParsingException e) {
+                       throw new BGPDocumentedException("Could not parse MP_REACH_NLRI: " + e.getMessage(), BGPError.OPT_ATTR_ERROR);
+               }
+       }
+}
\ No newline at end of file
index 44a1493aaced396cb3533f12f9b46ca9e18908ba..9e3b3a353d32fab1e36ebaae9046a8b5a33391ba 100644 (file)
@@ -131,7 +131,7 @@ public class MPReachParser {
                        final List<Ipv6Prefix> nlri6 = Ipv6Util.prefixListForBytes(bytes);
                        return new Ipv6Builder().setIpv6Prefixes(nlri6).build();
                } else if (afi == LinkstateAddressFamily.class) {
-                       return new LinkstateBuilder().setCLinkstateDestination(LinkStateParser.parseLSNlri(safi, bytes)).build();
+                       return new LinkstateBuilder().setCLinkstateDestination(LinkstateAttributeParser.parseLSNlri(safi, bytes)).build();
                }
                return null;
        }
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java
new file mode 100644 (file)
index 0000000..e82ad18
--- /dev/null
@@ -0,0 +1,23 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPError;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes2Builder;
+
+final class MPUnreachAttributeParser implements AttributeParser {
+       static final int TYPE = 15;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
+               try {
+                       final PathAttributes2 a = new PathAttributes2Builder().setMpUnreachNlri(MPReachParser.parseMPUnreach(bytes)).build();
+                       builder.addAugmentation(PathAttributes2.class, a);
+               } catch (final BGPParsingException e) {
+                       throw new BGPDocumentedException("Could not parse MP_UNREACH_NLRI: " + e.getMessage(), BGPError.OPT_ATTR_ERROR);
+               }
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java
new file mode 100644 (file)
index 0000000..8dd9bc6
--- /dev/null
@@ -0,0 +1,15 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.MultiExitDiscBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+final class MultiExitDiscriminatorAttributeParser implements AttributeParser {
+       static final int TYPE = 4;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               builder.setMultiExitDisc(new MultiExitDiscBuilder().setMed(ByteArray.bytesToLong(bytes)).build());
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java
new file mode 100644 (file)
index 0000000..d97870f
--- /dev/null
@@ -0,0 +1,16 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.CIpv4NextHopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.c.ipv4.next.hop.Ipv4NextHopBuilder;
+
+final class NextHopAttributeParser implements AttributeParser {
+       static final int TYPE = 3;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               builder.setCNextHop(new CIpv4NextHopBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(Ipv4Util.addressForBytes(bytes)).build()).build());
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java
new file mode 100644 (file)
index 0000000..9d478a8
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPError;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.OriginBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
+
+import com.google.common.primitives.UnsignedBytes;
+
+final class OriginAttributeParser implements AttributeParser {
+       static final int TYPE = 1;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
+               final BgpOrigin borigin = BgpOrigin.forValue(UnsignedBytes.toInt(bytes[0]));
+               if (borigin == null) {
+                       throw new BGPDocumentedException("Unknown Origin type.", BGPError.ORIGIN_ATTR_NOT_VALID, new byte[] { (byte) 0x01, (byte) 0x01, bytes[0] });
+               }
+
+               builder.setOrigin(new OriginBuilder().setValue(borigin).build());
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java
new file mode 100644 (file)
index 0000000..54fe62e
--- /dev/null
@@ -0,0 +1,17 @@
+package org.opendaylight.protocol.bgp.parser.impl.message.update;
+
+import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+
+final class OriginatorIdAttributeParser implements AttributeParser {
+       static final int TYPE = 9;
+
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
+               if (bytes.length != 4) {
+                       throw new IllegalArgumentException("Length of byte array for ORIGINATOR_ID should be 4, but is " + bytes.length);
+               }
+
+               builder.setOriginatorId(bytes);
+       }
+}
\ No newline at end of file
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/PathAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/PathAttributeParser.java
deleted file mode 100644 (file)
index 3eb0b78..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.protocol.bgp.parser.impl.message.update;
-
-import java.util.List;
-
-import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
-import org.opendaylight.protocol.bgp.parser.BGPError;
-import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSegmentParser.SegmentType;
-import org.opendaylight.protocol.bgp.parser.spi.AttributeRegistry;
-import org.opendaylight.protocol.concepts.IPv4;
-import org.opendaylight.protocol.concepts.Ipv4Util;
-import org.opendaylight.protocol.util.ByteArray;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.PathAttributes1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.PathAttributes1Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.Aggregator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AggregatorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AsPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AsPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.Communities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.ExtendedCommunities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.LocalPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.LocalPrefBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.MultiExitDisc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.MultiExitDiscBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.Origin;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.OriginBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.as.path.Segments;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.as.path.SegmentsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.CAListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.CASetBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.c.a.list.AsSequence;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.CIpv4NextHopBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.c.ipv4.next.hop.Ipv4NextHopBuilder;
-
-import com.google.common.collect.Lists;
-import com.google.common.primitives.UnsignedBytes;
-
-/**
- * 
- * Parser for different Path Attributes. Each attributes has its own method for parsing.
- * 
- */
-public class PathAttributeParser {
-
-       private static final int FLAGS_LENGTH = 1;
-
-       private static final int TYPE_LENGTH = 1;
-
-       private static AttributeRegistry reg = SimpleAttributeRegistry.INSTANCE;
-
-       private PathAttributeParser() {
-
-       }
-
-       /**
-        * Parse path attribute header (the same for all path attributes) and set type, length and value fields.
-        * 
-        * @param bytes byte array to be parsed.
-        * @return generic Path Attribute
-        * @throws BGPParsingException
-        * @throws BGPDocumentedException
-        */
-       public static PathAttributes parseAttribute(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
-               if (bytes == null || bytes.length == 0) {
-                       throw new BGPParsingException("Insufficient length of byte array: " + bytes.length);
-               }
-               int byteOffset = 0;
-               final PathAttributesBuilder builder = new PathAttributesBuilder();
-               while (byteOffset < bytes.length) {
-                       final boolean[] bits = ByteArray.parseBits(bytes[0]);
-                       final boolean optional = bits[0];
-                       final int attrLength = (bits[3]) ? ByteArray.bytesToInt(ByteArray.subByte(bytes, 2, 2)) : UnsignedBytes.toInt(bytes[2]);
-                       final int hdrLength = FLAGS_LENGTH + TYPE_LENGTH + ((bits[3]) ? 2 : 1);
-
-                       final byte[] attrBody = ByteArray.subByte(bytes, hdrLength, attrLength);
-
-                       boolean found = reg.parseAttribute(UnsignedBytes.toInt(bytes[1]), attrBody, builder);
-                       if (!optional && !found) {
-                               throw new BGPDocumentedException("Well known attribute not recognized.", BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED);
-                       }
-
-                       byteOffset += hdrLength + attrLength;
-               }
-               return builder.build();
-       }
-
-       /**
-        * Parses ORIGIN from bytes.
-        * 
-        * @param bytes byte array to be parsed
-        * @return {@link Origin} BGP origin value
-        * @throws BGPDocumentedException
-        */
-       static Origin parseOrigin(final byte[] bytes) throws BGPDocumentedException {
-               final BgpOrigin borigin = BgpOrigin.forValue(UnsignedBytes.toInt(bytes[0]));
-               if (borigin == null) {
-                       throw new BGPDocumentedException("Unknown Origin type.", BGPError.ORIGIN_ATTR_NOT_VALID, new byte[] { (byte) 0x01, (byte) 0x01,
-                                       bytes[0] });
-               }
-               return new OriginBuilder().setValue(borigin).build();
-       }
-
-       /**
-        * Parses AS_PATH from bytes.
-        * 
-        * @param bytes byte array to be parsed
-        * @return new ASPath object
-        * @throws BGPDocumentedException if there is no AS_SEQUENCE present (mandatory)
-        * @throws BGPParsingException
-        */
-       static AsPath parseAsPath(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
-               int byteOffset = 0;
-               final List<Segments> ases = Lists.newArrayList();
-               boolean isSequence = false;
-               while (byteOffset < bytes.length) {
-                       final int type = UnsignedBytes.toInt(bytes[byteOffset]);
-                       final SegmentType segmentType = AsPathSegmentParser.parseType(type);
-                       if (segmentType == null) {
-                               throw new BGPParsingException("AS Path segment type unknown : " + type);
-                       }
-                       byteOffset += AsPathSegmentParser.TYPE_LENGTH;
-
-                       final int count = UnsignedBytes.toInt(bytes[byteOffset]);
-                       byteOffset += AsPathSegmentParser.LENGTH_SIZE;
-
-                       if (segmentType == SegmentType.AS_SEQUENCE) {
-                               final List<AsSequence> numbers = AsPathSegmentParser.parseAsSequence(count,
-                                               ByteArray.subByte(bytes, byteOffset, count * AsPathSegmentParser.AS_NUMBER_LENGTH));
-                               ases.add(new SegmentsBuilder().setCSegment(new CAListBuilder().setAsSequence(numbers).build()).build());
-                               isSequence = true;
-                       } else {
-                               final List<AsNumber> list = AsPathSegmentParser.parseAsSet(count,
-                                               ByteArray.subByte(bytes, byteOffset, count * AsPathSegmentParser.AS_NUMBER_LENGTH));
-                               ases.add(new SegmentsBuilder().setCSegment(new CASetBuilder().setAsSet(list).build()).build());
-
-                       }
-                       byteOffset += count * AsPathSegmentParser.AS_NUMBER_LENGTH;
-               }
-
-               if (!isSequence && bytes.length != 0) {
-                       throw new BGPDocumentedException("AS_SEQUENCE must be present in AS_PATH attribute.", BGPError.AS_PATH_MALFORMED);
-               }
-               return new AsPathBuilder().setSegments(ases).build();
-       }
-
-       /**
-        * Parse NEXT_HOP from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return new NextHop object, it's always IPv4 (basic BGP-4)
-        */
-       static CNextHop parseNextHop(final byte[] bytes) {
-               return new CIpv4NextHopBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(Ipv4Util.addressForBytes(bytes)).build()).build();
-       }
-
-       /**
-        * Parse MULTI_EXIT_DISC (integer) from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return integer representing MULTI_EXIT_DISC path attribute
-        */
-       static MultiExitDisc parseMultiExitDisc(final byte[] bytes) {
-               return new MultiExitDiscBuilder().setMed(ByteArray.bytesToLong(bytes)).build();
-       }
-
-       /**
-        * Parse LOCAL_PREF (integer) from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return integer representing LOCAL_PREF path attribute
-        */
-       static LocalPref parseLocalPref(final byte[] bytes) {
-               return new LocalPrefBuilder().setPref(ByteArray.bytesToLong(bytes)).build();
-       }
-
-       /**
-        * Parse AGGREGATOR from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return {@link Aggregator} BGP Aggregator
-        */
-       static Aggregator parseAggregator(final byte[] bytes) {
-               final AsNumber asNumber = new AsNumber(ByteArray.bytesToLong(ByteArray.subByte(bytes, 0, AsPathSegmentParser.AS_NUMBER_LENGTH)));
-               final Ipv4Address address = new Ipv4Address(IPv4.FAMILY.addressForBytes(
-                               ByteArray.subByte(bytes, AsPathSegmentParser.AS_NUMBER_LENGTH, 4)).toString());
-               return new AggregatorBuilder().setAsNumber(asNumber).setNetworkAddress(address).build();
-       }
-
-       /**
-        * Parse MP_REACH_NLRI from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return new specific MPReach object with reachable flag set to true
-        * @throws BGPDocumentedException
-        */
-       static void parseMPReach(final PathAttributesBuilder b, final byte[] bytes) throws BGPDocumentedException {
-
-               try {
-                       final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes1 a = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes1Builder().setMpReachNlri(
-                                       MPReachParser.parseMPReach(bytes)).build();
-
-                       b.addAugmentation(
-                                       org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.PathAttributes1.class, a);
-               } catch (final BGPParsingException e) {
-                       throw new BGPDocumentedException("Could not parse MP_REACH_NLRI: " + e.getMessage(), BGPError.OPT_ATTR_ERROR);
-               }
-       }
-
-       /**
-        * Parse MP_UNREACH_NLRI from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return new specific MPReach object with reachable flag set to false
-        * @throws BGPDocumentedException
-        */
-       static void parseMPUnreach(final PathAttributesBuilder b, final byte[] bytes) throws BGPDocumentedException {
-               try {
-                       final PathAttributes2 a = new PathAttributes2Builder().setMpUnreachNlri(MPReachParser.parseMPUnreach(bytes)).build();
-
-                       b.addAugmentation(PathAttributes2.class, a);
-               } catch (final BGPParsingException e) {
-                       throw new BGPDocumentedException("Could not parse MP_UNREACH_NLRI: " + e.getMessage(), BGPError.OPT_ATTR_ERROR);
-               }
-       }
-
-       /**
-        * Parse set of EXTENDED_COMMUNITIES from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return new specific Extended Community object
-        * @throws BGPDocumentedException l
-        */
-       static List<ExtendedCommunities> parseExtendedCommunities(final byte[] bytes) throws BGPDocumentedException {
-               final List<ExtendedCommunities> set = Lists.newArrayList();
-               int i = 0;
-               while (i < bytes.length) {
-                       set.add((ExtendedCommunities) CommunitiesParser.parseExtendedCommunity(ByteArray.subByte(bytes, i,
-                                       CommunitiesParser.EXTENDED_COMMUNITY_LENGTH)));
-                       i += CommunitiesParser.EXTENDED_COMMUNITY_LENGTH;
-               }
-               return set;
-       }
-
-       /**
-        * Parse set of COMMUNITIES from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return new specific Community object
-        * @throws BGPDocumentedException
-        */
-       static List<Communities> parseCommunities(final byte[] bytes) throws BGPDocumentedException {
-               final List<Communities> set = Lists.newArrayList();
-               int i = 0;
-               while (i < bytes.length) {
-                       set.add((Communities) CommunitiesParser.parseCommunity(ByteArray.subByte(bytes, i, CommunitiesParser.COMMUNITY_LENGTH)));
-                       i += CommunitiesParser.COMMUNITY_LENGTH;
-               }
-               return set;
-       }
-
-       /**
-        * Parse list of Cluster Identifiers.
-        * 
-        * @param bytes byte array to be parsed
-        * @return new List of Cluster Identifiers
-        */
-       static List<ClusterIdentifier> parseClusterList(final byte[] bytes) {
-               final List<ClusterIdentifier> list = Lists.newArrayList();
-               int i = 0;
-               while (i < bytes.length) {
-                       list.add(new ClusterIdentifier(ByteArray.subByte(bytes, i, 4)));
-                       i += 4;
-               }
-               return list;
-       }
-
-       /**
-        * Parses ORIGINATOR_ID, which is BGP Identifier, which is IP address of the speaker.
-        * 
-        * @param bytes byte array to be parsed
-        * @return IP address of the speaker
-        */
-       static byte[] parseOriginatorId(final byte[] bytes) {
-               if (bytes.length != 4) {
-                       throw new IllegalArgumentException("Length of byte array for ORIGINATOR_ID should be 4, but is " + bytes.length);
-               }
-               return bytes;
-       }
-
-       /**
-        * Parse LINK_STATE from bytes
-        * 
-        * @param bytes byte array to be parsed
-        * @return Map, where the key is the type of a tlv and the value is the value of the tlv
-        * @throws BGPParsingException
-        */
-       static void parseLinkState(final PathAttributesBuilder builder, final byte[] bytes) throws BGPParsingException {
-               final PathAttributes1 a = new PathAttributes1Builder().setLinkstatePathAttribute(LinkStateParser.parseLinkState(bytes)).build();
-               builder.addAugmentation(PathAttributes1.class, a);
-       }
-}
index 814c4b52d8bd25ddc2c97ebae7bd34f9bdbd3802..f528e15b8a5eb1b357a7b60ae80a0b9eb7755c2e 100644 (file)
@@ -8,17 +8,20 @@
 package org.opendaylight.protocol.bgp.parser.impl.message.update;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.concepts.HandlerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.path.attributes.AtomicAggregateBuilder;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
 import com.google.common.base.Preconditions;
+import com.google.common.primitives.UnsignedBytes;
 
 public final class SimpleAttributeRegistry implements AttributeRegistry {
        public static final AttributeRegistry INSTANCE;
@@ -26,106 +29,22 @@ public final class SimpleAttributeRegistry implements AttributeRegistry {
        static {
                final AttributeRegistry reg = new SimpleAttributeRegistry();
 
-               reg.registerAttributeParser(1, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
-                               builder.setOrigin(PathAttributeParser.parseOrigin(bytes));
-                       }
-               });
-               reg.registerAttributeParser(2, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder)     throws BGPDocumentedException, BGPParsingException {
-                               builder.setAsPath(PathAttributeParser.parseAsPath(bytes));
-                       }
-               });
-               reg.registerAttributeParser(3, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               builder.setCNextHop(PathAttributeParser.parseNextHop(bytes));
-                       }
-               });
-               reg.registerAttributeParser(4, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               builder.setMultiExitDisc(PathAttributeParser.parseMultiExitDisc(bytes));
-                       }
-               });
-               reg.registerAttributeParser(5, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               builder.setLocalPref(PathAttributeParser.parseLocalPref(bytes));
-                       }
-               });
-               reg.registerAttributeParser(6, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               builder.setAtomicAggregate(new AtomicAggregateBuilder().build());
-                       }
-               });
-               reg.registerAttributeParser(7, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               builder.setAggregator(PathAttributeParser.parseAggregator(bytes));
-                       }
-               });
-               reg.registerAttributeParser(8, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
-                               builder.setCommunities(PathAttributeParser.parseCommunities(bytes));
-                       }
-               });
-               reg.registerAttributeParser(9, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               builder.setOriginatorId(PathAttributeParser.parseOriginatorId(bytes));
-                       }
-               });
-
-               reg.registerAttributeParser(10, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               builder.setClusterId(PathAttributeParser.parseClusterList(bytes));
-                       }
-               });
-
-               reg.registerAttributeParser(14, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
-                               PathAttributeParser.parseMPReach(builder, bytes);
-                       }
-               });
-               reg.registerAttributeParser(15, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
-                               PathAttributeParser.parseMPUnreach(builder, bytes);
-                       }
-               });
-               reg.registerAttributeParser(16, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
-                               builder.setExtendedCommunities(PathAttributeParser.parseExtendedCommunities(bytes));
-                       }
-               });
-               reg.registerAttributeParser(17, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               // AS4 Aggregator is ignored
-                       }
-               });
-               reg.registerAttributeParser(18, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) {
-                               // AS4 Path is ignored
-                       }
-               });
-
-               // FIXME: update to IANA number once it is known
-               reg.registerAttributeParser(99, new AttributeParser() {
-                       @Override
-                       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPParsingException {
-                               PathAttributeParser.parseLinkState(builder, bytes);
-                       }
-               });
+               reg.registerAttributeParser(OriginAttributeParser.TYPE, new OriginAttributeParser());
+               reg.registerAttributeParser(AsPathAttributeParser.TYPE, new AsPathAttributeParser());
+               reg.registerAttributeParser(NextHopAttributeParser.TYPE, new NextHopAttributeParser());
+               reg.registerAttributeParser(MultiExitDiscriminatorAttributeParser.TYPE, new MultiExitDiscriminatorAttributeParser());
+               reg.registerAttributeParser(LocalPreferenceAttributeParser.TYPE, new LocalPreferenceAttributeParser());
+               reg.registerAttributeParser(AtomicAggregateAttributeParser.TYPE, new AtomicAggregateAttributeParser());
+               reg.registerAttributeParser(AggregatorAttributeParser.TYPE, new AggregatorAttributeParser());
+               reg.registerAttributeParser(CommunitiesAttributeParser.TYPE, new CommunitiesAttributeParser());
+               reg.registerAttributeParser(OriginatorIdAttributeParser.TYPE, new OriginatorIdAttributeParser());
+               reg.registerAttributeParser(ClusterIdAttributeParser.TYPE, new ClusterIdAttributeParser());
+               reg.registerAttributeParser(MPReachAttributeParser.TYPE, new MPReachAttributeParser());
+               reg.registerAttributeParser(MPUnreachAttributeParser.TYPE, new MPUnreachAttributeParser());
+               reg.registerAttributeParser(ExtendedCommunitiesAttributeParser.TYPE, new ExtendedCommunitiesAttributeParser());
+               reg.registerAttributeParser(AS4AggregatorAttributeParser.TYPE, new AS4AggregatorAttributeParser());
+               reg.registerAttributeParser(AS4PathAttributeParser.TYPE, new AS4PathAttributeParser());
+               reg.registerAttributeParser(LinkstateAttributeParser.TYPE, new LinkstateAttributeParser());
 
                INSTANCE = reg;
        }
@@ -133,9 +52,9 @@ public final class SimpleAttributeRegistry implements AttributeRegistry {
        private final HandlerRegistry<DataContainer, AttributeParser, AttributeSerializer> handlers = new HandlerRegistry<>();
 
        @Override
-       public AutoCloseable registerAttributeParser(final int messageType, final AttributeParser parser) {
-               Preconditions.checkArgument(messageType >= 0 && messageType <= 255);
-               return handlers.registerParser(messageType, parser);
+       public AutoCloseable registerAttributeParser(final int attributeType, final AttributeParser parser) {
+               Preconditions.checkArgument(attributeType >= 0 && attributeType <= 255);
+               return handlers.registerParser(attributeType, parser);
        }
 
        @Override
@@ -143,15 +62,41 @@ public final class SimpleAttributeRegistry implements AttributeRegistry {
                return handlers.registerSerializer(paramClass, serializer);
        }
 
-       @Override
-       public boolean parseAttribute(final int attributeType, final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException, BGPParsingException {
-               final AttributeParser parser = handlers.getParser(attributeType);
+       private int parseAttribute( final byte[] bytes, final int offset, final PathAttributesBuilder builder)
+                       throws BGPDocumentedException, BGPParsingException {
+               // FIXME: validate minimum length
+               final boolean[] flags = ByteArray.parseBits(bytes[offset]);
+               final int type = UnsignedBytes.toInt(bytes[offset + 1]);
+               final int hdrlen;
+               final int len;
+               if (flags[3]) {
+                       len = UnsignedBytes.toInt(bytes[offset + 2]) * 256 + UnsignedBytes.toInt(bytes[offset + 3]);
+                       hdrlen = 4;
+               } else {
+                       len = UnsignedBytes.toInt(bytes[offset + 2]);
+                       hdrlen = 3;
+               }
+
+               final AttributeParser parser = handlers.getParser(type);
                if (parser == null) {
-                       return false;
+                       if (!flags[0]) {
+                               throw new BGPDocumentedException("Well known attribute not recognized.", BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED);
+                       }
+               } else {
+                       parser.parseAttribute(ByteArray.subByte(bytes, offset + hdrlen, len), builder);
                }
 
-               parser.parseAttribute(bytes, builder);
-               return true;
+               return hdrlen + len;
+       }
+
+       @Override
+       public PathAttributes parseAttributes(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
+               int byteOffset = 0;
+               final PathAttributesBuilder builder = new PathAttributesBuilder();
+               while (byteOffset < bytes.length) {
+                       byteOffset += parseAttribute(bytes, byteOffset, builder);
+               }
+               return builder.build();
        }
 
        @Override
index 11870ba5afb2e89111ab04fccda1cb6e677d02f7..0ad3e218dfeb7d0fa7686097b2b058a928d5f889 100644 (file)
@@ -14,7 +14,7 @@ import static org.junit.Assert.fail;
 import org.junit.Test;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.bgp.parser.impl.message.update.PathAttributeParser;
+import org.opendaylight.protocol.bgp.parser.impl.message.update.SimpleAttributeRegistry;
 
 /*
  * To test incorrect values.
@@ -24,7 +24,7 @@ public class PathAttributeParserTest {
        @Test
        public void testOriginParser() {
                try {
-                       PathAttributeParser.parseAttribute(new byte[] { 0x40, 0x01, 0x01, 0x04 });
+                       SimpleAttributeRegistry.INSTANCE.parseAttributes(new byte[] { 0x40, 0x01, 0x01, 0x04 });
                        fail("This needs to fail.");
                } catch (final BGPDocumentedException e) {
                        assertEquals("Unknown Origin type.", e.getMessage());
index ea13945f823e7dae9d188b61496321c73001919e..ac479953528859188ec0e0fab8cff826b8a2ecaf 100644 (file)
@@ -9,13 +9,13 @@ package org.opendaylight.protocol.bgp.parser.spi;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributes;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
 public interface AttributeRegistry {
        public AutoCloseable registerAttributeParser(int attributeType, AttributeParser parser);
        public AutoCloseable registerAttributeSerializer(Class<? extends DataObject> attributeClass, AttributeSerializer serializer);
 
-       public boolean parseAttribute(int attributeType, final byte[] bytes, PathAttributesBuilder builder) throws BGPDocumentedException, BGPParsingException;
+       public PathAttributes parseAttributes(final byte[] bytes) throws BGPDocumentedException, BGPParsingException;
        public byte[] serializeAttribute(DataObject attribute);
 }