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;
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.
*
*/
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);
*/
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 --------------------------------------------------
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);
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
* @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 })) {
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(
--- /dev/null
+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
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;
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;
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;
*
* @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;
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);
}
/**
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;
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;
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;
--- /dev/null
+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
--- /dev/null
+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
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;
}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
+++ /dev/null
-/*
- * 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);
- }
-}
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;
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;
}
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
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
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.
@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());
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);
}