<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bgp-parser-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-parser-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
* 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;
+package org.opendaylight.protocol.bgp.linkstate;
-import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
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;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
+import org.opendaylight.protocol.util.ByteList;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.AdministrativeGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.AreaIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.DomainIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.ExtendedRouteTag;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Identifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.IgpBits.UpDown;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv4InterfaceIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv4RouterIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv6InterfaceIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv6RouterIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.IsisAreaIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkProtectionType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.MplsProtocolMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NlriType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NodeFlagBits;
-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.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.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.RouteTag;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.SharedRiskLinkGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.TopologyIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifierBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.link.state.UnreservedBandwidthBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestinationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptors;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptorsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptors;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptorsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptors;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptorsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.RemoteNodeDescriptors;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.CRouterIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisPseudonodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfPseudonodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.node.IsisNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.pseudonode.IsisPseudonodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.node.OspfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.pseudonode.OspfPseudonodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.prefix.state.IgpBitsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.LinkstatePathAttribute;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.LinkstatePathAttributeBuilder;
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.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.bgp.message.rev130918.update.PathAttributesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Bandwidth;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.IgpMetric;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.IsoSystemIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Metric;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.TeMetric;
import org.slf4j.Logger;
*
* @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
+ public 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 int LENGTH_SIZE = 2;
- private static final int ROUTE_DISTINGUISHER_LENGTH = 8;
-
- private static final int PROTOCOL_ID_LENGTH = 1;
-
- private static final int IDENTIFIER_LENGTH = 8;
-
private static final Set<Integer> nodeTlvs = Sets.newHashSet(263, 1024, 1025, 1026, 1027, 1028, 1029);
private static final Set<Integer> linkTlvs = Sets.newHashSet(1028, 1029, 1030, 1031, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095,
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);
}
- /**
- * Parses common parts for Link State Nodes, Links and Prefixes, that includes protocol ID and identifier tlv.
- *
- * @param reachable
- * @param safi
- * @param bytes
- * @return BGPLinkMP or BGPNodeMP
- * @throws BGPParsingException
- */
- protected static CLinkstateDestination parseLSNlri(final Class<? extends SubsequentAddressFamily> safi, final byte[] bytes)
- throws BGPParsingException {
- if (bytes.length == 0) {
- return null;
- }
- int byteOffset = 0;
-
- final CLinkstateDestinationBuilder builder = new CLinkstateDestinationBuilder();
-
- while (byteOffset != bytes.length) {
- final NlriType type = NlriType.forValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH)));
- builder.setNlriType(type);
-
- byteOffset += TYPE_LENGTH;
- // length means total length of the tlvs including route distinguisher not including the type field
- final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
- byteOffset += LENGTH_SIZE;
- RouteDistinguisher distinguisher = null;
- if (safi == MplsLabeledVpnSubsequentAddressFamily.class) {
- // this parses route distinguisher
- distinguisher = new RouteDistinguisher(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(bytes, byteOffset,
- ROUTE_DISTINGUISHER_LENGTH))));
- builder.setDistinguisher(distinguisher);
- byteOffset += ROUTE_DISTINGUISHER_LENGTH;
- }
- // parse source protocol
- final ProtocolId sp = ProtocolId.forValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, PROTOCOL_ID_LENGTH)));
- byteOffset += PROTOCOL_ID_LENGTH;
- builder.setProtocolId(sp);
-
- // parse identifier
- final Identifier identifier = new Identifier(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(bytes, byteOffset,
- IDENTIFIER_LENGTH))));
- byteOffset += IDENTIFIER_LENGTH;
- builder.setIdentifier(identifier);
-
- // if we are dealing with linkstate nodes/links, parse local node descriptor
- NodeIdentifier localDescriptor = null;
- int locallength = 0;
- final int localtype = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
- byteOffset += TYPE_LENGTH;
- locallength = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
- byteOffset += LENGTH_SIZE;
- if (localtype == 256) {
- localDescriptor = parseNodeDescriptors(ByteArray.subByte(bytes, byteOffset, locallength));
- }
- byteOffset += locallength;
- builder.setLocalNodeDescriptors((LocalNodeDescriptors) localDescriptor);
- final int restLength = length - ((safi == MplsLabeledVpnSubsequentAddressFamily.class) ? ROUTE_DISTINGUISHER_LENGTH : 0)
- - PROTOCOL_ID_LENGTH - IDENTIFIER_LENGTH - TYPE_LENGTH - LENGTH_SIZE - locallength;
- logger.debug("Restlength {}", restLength);
- switch (type) {
- case Link:
- parseLink(builder, ByteArray.subByte(bytes, byteOffset, restLength));
- break;
- case Ipv4Prefix:
- case Ipv6Prefix:
- builder.setPrefixDescriptors(parsePrefixDescriptors(localDescriptor, ByteArray.subByte(bytes, byteOffset, restLength)));
- break;
- case Node:
- // node nlri is already parsed as it contains only the common fields for node and link nlri
- break;
- }
- byteOffset += restLength;
- }
- return builder.build();
- }
public static boolean verifyLink(final Set<Integer> keys) {
for (final Integer i : keys) {
return true;
}
- private static NodeIdentifier parseLink(final CLinkstateDestinationBuilder builder, final byte[] bytes) throws BGPParsingException {
- int byteOffset = 0;
- final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
- byteOffset += TYPE_LENGTH;
- final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
- byteOffset += LENGTH_SIZE;
- final NodeIdentifier remote = null;
- if (type == 257) {
- builder.setRemoteNodeDescriptors((RemoteNodeDescriptors) parseNodeDescriptors(ByteArray.subByte(bytes, byteOffset, length)));
- byteOffset += length;
- }
- builder.setLinkDescriptors(parseLinkDescriptors(ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset)));
- return remote;
- }
-
- private static LinkDescriptors parseLinkDescriptors(final byte[] bytes) throws BGPParsingException {
- int byteOffset = 0;
- final LinkDescriptorsBuilder builder = new LinkDescriptorsBuilder();
- while (byteOffset != bytes.length) {
- final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
- byteOffset += TYPE_LENGTH;
- final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
- byteOffset += LENGTH_SIZE;
- final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
- logger.debug("Parsing Link Descriptor: {}", Arrays.toString(value));
- switch (type) {
- case 258:
- builder.setLinkLocalIdentifier(ByteArray.subByte(value, 0, 4));
- builder.setLinkRemoteIdentifier(ByteArray.subByte(value, 4, 4));
- logger.trace("Parsed link local {} remote {} Identifiers.", builder.getLinkLocalIdentifier(),
- builder.getLinkRemoteIdentifier());
- break;
- case 259:
- final Ipv4InterfaceIdentifier lipv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
- builder.setIpv4InterfaceAddress(lipv4);
- logger.trace("Parsed IPv4 interface address {}.", lipv4);
- break;
- case 260:
- final Ipv4InterfaceIdentifier ripv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
- builder.setIpv4NeighborAddress(ripv4);
- logger.trace("Parsed IPv4 neighbor address {}.", ripv4);
- break;
- case 261:
- final Ipv6InterfaceIdentifier lipv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
- builder.setIpv6InterfaceAddress(lipv6);
- logger.trace("Parsed IPv6 interface address {}.", lipv6);
- break;
- case 262:
- final Ipv6InterfaceIdentifier ripv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
- builder.setIpv6NeighborAddress(ripv6);
- logger.trace("Parsed IPv6 neighbor address {}.", ripv6);
- break;
- case 263:
- final TopologyIdentifier topId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
- builder.setMultiTopologyId(topId);
- logger.trace("Parsed topology identifier {}.", topId);
- break;
- default:
- throw new BGPParsingException("Link Descriptor not recognized, type: " + type);
- }
- byteOffset += length;
- }
- logger.debug("Finished parsing Link descriptors.");
- return builder.build();
- }
-
- private static NodeIdentifier parseNodeDescriptors(final byte[] bytes) throws BGPParsingException {
- int byteOffset = 0;
- AsNumber asnumber = null;
- DomainIdentifier bgpId = null;
- AreaIdentifier ai = null;
- CRouterIdentifier routerId = null;
- while (byteOffset != bytes.length) {
- final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
- byteOffset += TYPE_LENGTH;
- final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
- byteOffset += LENGTH_SIZE;
- final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
- logger.debug("Parsing Node Descriptor: {}", Arrays.toString(value));
- switch (type) {
- case 512:
- asnumber = new AsNumber(ByteArray.bytesToLong(value));
- logger.trace("Parsed AS number {}", asnumber);
- break;
- case 513:
- bgpId = new DomainIdentifier(value);
- logger.trace("Parsed bgpId {}", bgpId);
- break;
- case 514:
- ai = new AreaIdentifier(value);
- logger.trace("Parsed area identifier {}", ai);
- break;
- case 515:
- if (value.length == 6) {
- routerId = new CIsisNodeBuilder().setIsisNode(
- new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
- } else if (value.length == 7) {
- if (value[6] == 0) {
- logger.warn("PSN octet is 0. Ignoring System ID.");
- routerId = new CIsisNodeBuilder().setIsisNode(
- new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
- break;
- } else {
- final IsIsRouterIdentifier iri = new IsIsRouterIdentifierBuilder().setIsoSystemId(
- new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build();
- routerId = new CIsisPseudonodeBuilder().setIsisPseudonode(
- new IsisPseudonodeBuilder().setIsIsRouterIdentifier(iri).setPsn((short) UnsignedBytes.toInt(value[6])).build()).build();
- }
- } else if (value.length == 4) {
- routerId = new COspfNodeBuilder().setOspfNode(
- new OspfNodeBuilder().setOspfRouterId(ByteArray.subByte(value, 0, 4)).build()).build();
- } else if (value.length == 8) {
- final byte[] o = ByteArray.subByte(value, 0, 4); // FIXME: OSPFv3 vs OSPFv2
- final OspfInterfaceIdentifier a = new OspfInterfaceIdentifier(ByteArray.subByte(value, 4, 4));
- routerId = new COspfPseudonodeBuilder().setOspfPseudonode(
- new OspfPseudonodeBuilder().setOspfRouterId(o).setLanInterface(a).build()).build();
- }
- logger.trace("Parsed Router Identifier {}", routerId);
- break;
- default:
- throw new BGPParsingException("Node Descriptor not recognized, type: " + type);
- }
- byteOffset += length;
- }
- logger.debug("Finished parsing Node descriptors.");
- return new LocalNodeDescriptorsBuilder().setAsNumber(asnumber).setDomainId(bgpId).setAreaId(ai).setCRouterIdentifier(routerId).build();
- }
-
- private static PrefixDescriptors parsePrefixDescriptors(final NodeIdentifier localDescriptor, final byte[] bytes)
- throws BGPParsingException {
- int byteOffset = 0;
- final PrefixDescriptorsBuilder builder = new PrefixDescriptorsBuilder();
- while (byteOffset != bytes.length) {
- final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
- byteOffset += TYPE_LENGTH;
- final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
- byteOffset += LENGTH_SIZE;
- final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
- logger.trace("Parsing Prefix Descriptor: {}", Arrays.toString(value));
- switch (type) {
- case 263:
- final TopologyIdentifier topologyId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
- builder.setMultiTopologyId(topologyId);
- logger.trace("Parsed Topology Identifier: {}", topologyId);
- break;
- case 264:
- final int rt = ByteArray.bytesToInt(value);
- final OspfRouteType routeType = OspfRouteType.forValue(rt);
- if (routeType == null)
- throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
- builder.setOspfRouteType(routeType);
- logger.trace("Parser RouteType: {}", routeType);
- break;
- case 265:
- IpPrefix prefix = null;
- final int prefixLength = UnsignedBytes.toInt(value[0]);
- final int size = prefixLength / 8 + ((prefixLength % 8 == 0) ? 0 : 1);
- if (size != value.length - 1) {
- 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)
- prefix = new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
- else
- prefix = new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
- builder.setIpReachabilityInformation(prefix);
- logger.trace("Parsed IP reachability info: {}", prefix);
- break;
- default:
- throw new BGPParsingException("Prefix Descriptor not recognized, type: " + type);
- }
- byteOffset += length;
- }
- logger.debug("Finished parsing Prefix descriptors.");
- return builder.build();
- }
-
protected static LinkstatePathAttribute parseLinkState(final byte[] bytes) throws BGPParsingException {
final Map<Integer, ByteList> map = new HashMap<Integer, ByteList>();
int byteOffset = 0;
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;
}
}
- augment "/bgp-msg:update/bgp-msg:path-attributes/bgp-mp:mp-reach-nlri/bgp-mp:advertized-routes/bgp-mp:nlri" {
- case linkstate {
+ augment "/bgp-msg:update/bgp-msg:path-attributes/bgp-mp:mp-reach-nlri/bgp-mp:advertized-routes/bgp-mp:destination-type" {
+ case destination-linkstate {
uses linkstate-destination;
}
}
- augment "/bgp-msg:update/bgp-msg:path-attributes/bgp-mp:mp-unreach-nlri/bgp-mp:withdrawn-routes/bgp-mp:nlri" {
- case linkstate {
+ augment "/bgp-msg:update/bgp-msg:path-attributes/bgp-mp:mp-unreach-nlri/bgp-mp:withdrawn-routes/bgp-mp:destination-type" {
+ case destination-linkstate {
uses linkstate-destination;
}
}
}
grouping destination {
- choice nlri {
- case ipv4 {
+ choice destination-type {
+ case destination-ipv4 {
when "../../afi = ipv4";
leaf-list ipv4-prefixes {
type inet:ipv4-prefix;
}
}
- case ipv6 {
+ case destination-ipv6 {
when "../../afi = ipv6";
leaf-list ipv6-prefixes {
type inet:ipv6-prefix;
+++ /dev/null
-package org.opendaylight.protocol.bgp.parser.impl;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateSubsequentAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
-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.bgp.types.rev130919.UnicastSubsequentAddressFamily;
-
-public final class ParserUtil {
-
- private ParserUtil() { }
-
- public static Class<? extends AddressFamily> afiForValue(final int value) {
- // FIXME: this needs to be extensible through an SPI interface
- switch (value) {
- case 1:
- return Ipv4AddressFamily.class;
- case 2:
- return Ipv6AddressFamily.class;
- case 16388:
- return LinkstateAddressFamily.class;
- }
-
- return null;
- }
-
- public static Class<? extends SubsequentAddressFamily> safiForValue(final int value) {
- // FIXME: this needs to be extensible through an SPI interface
- switch (value) {
- case 1:
- return UnicastSubsequentAddressFamily.class;
- case 128:
- return MplsLabeledVpnSubsequentAddressFamily.class;
- case 71:
- return LinkstateSubsequentAddressFamily.class;
- }
-
- return null;
- }
-
- public static int valueForSafi(final Class<? extends SubsequentAddressFamily> safi) {
- // FIXME: this needs to be extensible through an SPI interface
- if (safi == UnicastSubsequentAddressFamily.class) {
- return 1;
- } else if (safi == MplsLabeledVpnSubsequentAddressFamily.class) {
- return 128;
- } else if (safi == LinkstateSubsequentAddressFamily.class) {
- return 71;
- } else {
- throw new IllegalArgumentException("Unhandled SAFI class " + safi.getClass());
- }
- }
-
- public static int valueForAfi(final Class<? extends AddressFamily> afi) {
- // FIXME: this needs to be extensible through an SPI interface
- if (afi == Ipv4AddressFamily.class) {
- return 1;
- } else if (afi == Ipv6AddressFamily.class) {
- return 2;
- } else if (afi == LinkstateAddressFamily.class) {
- return 16388;
- } else {
- throw new IllegalArgumentException("Unhandled AFI class " + afi.getClass());
- }
- }
-}
--- /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;
+
+import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+
+import com.google.common.base.Preconditions;
+
+public final class SimpleAddressFamilyRegistry implements AddressFamilyRegistry {
+ public static final AddressFamilyRegistry INSTANCE;
+
+ static {
+ final AddressFamilyRegistry reg = new SimpleAddressFamilyRegistry();
+
+ reg.registerAddressFamily(Ipv4AddressFamily.class, 1);
+ reg.registerAddressFamily(Ipv6AddressFamily.class, 2);
+ reg.registerAddressFamily(LinkstateAddressFamily.class, 16388);
+
+ INSTANCE = reg;
+ }
+
+ private final SimpleFamilyRegistry<AddressFamily, Integer> registry = new SimpleFamilyRegistry<>();
+
+ @Override
+ public AutoCloseable registerAddressFamily(final Class<? extends AddressFamily> clazz, final int number) {
+ Preconditions.checkArgument(number >= 0 && number <= 65535);
+ return registry.registerFamily(clazz, number);
+ }
+
+ @Override
+ public Class<? extends AddressFamily> classForFamily(final int number) {
+ return registry.classForFamily(number);
+ }
+
+ @Override
+ public Integer numberForClass(final Class<? extends AddressFamily> clazz) {
+ return registry.numberForClass(clazz);
+ }
+}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.Keepalive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.Notify;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.Open;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.Notification;
public final class SimpleBGPMessageFactory extends AbstractMessageRegistry {
static {
final SimpleBGPMessageFactory reg = new SimpleBGPMessageFactory();
- reg.registerMessageParser(1, BGPOpenMessageParser.PARSER);
+ reg.registerMessageParser(BGPOpenMessageParser.TYPE, BGPOpenMessageParser.PARSER);
reg.registerMessageSerializer(Open.class, BGPOpenMessageParser.SERIALIZER);
- reg.registerMessageParser(2, BGPUpdateMessageParser.PARSER);
+ reg.registerMessageParser(BGPUpdateMessageParser.TYPE, BGPUpdateMessageParser.PARSER);
// Serialization of Update message is not supported
- reg.registerMessageParser(3, BGPNotificationMessageParser.PARSER);
+ reg.registerMessageParser(BGPNotificationMessageParser.TYPE, BGPNotificationMessageParser.PARSER);
reg.registerMessageSerializer(Notify.class, BGPNotificationMessageParser.SERIALIZER);
- reg.registerMessageParser(4, BGPKeepAliveMessageParser.PARSER);
+ reg.registerMessageParser(BGPKeepAliveMessageParser.TYPE, BGPKeepAliveMessageParser.PARSER);
reg.registerMessageSerializer(Keepalive.class, BGPKeepAliveMessageParser.SERIALIZER);
INSTANCE = reg;
}
- private final HandlerRegistry<Notification, MessageParser, MessageSerializer> handlers = new HandlerRegistry<>();
+ private final HandlerRegistry<DataContainer, MessageParser, MessageSerializer> handlers = new HandlerRegistry<>();
private SimpleBGPMessageFactory() {
@Override
protected byte[] serializeMessageImpl(final Notification message) {
- final MessageSerializer serializer = handlers.getSerializer(message);
+ final MessageSerializer serializer = handlers.getSerializer(message.getImplementedInterface());
if (serializer == null) {
return null;
}
--- /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;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.protocol.concepts.AbstractRegistration;
+
+import com.google.common.base.Preconditions;
+
+final class SimpleFamilyRegistry<CLASS, NUMBER> {
+ private final Map<Class<? extends CLASS>, NUMBER> classToNumber = new ConcurrentHashMap<>();
+ private final Map<NUMBER, Class<? extends CLASS>> numberToClass = new ConcurrentHashMap<>();
+
+ public synchronized AutoCloseable registerFamily(final Class<? extends CLASS> clazz, final NUMBER number) {
+ Preconditions.checkNotNull(clazz);
+
+ final Class<?> c = numberToClass.get(number);
+ Preconditions.checkState(c == null, "Number " + number + " already registered to " + c);
+
+ final NUMBER n = classToNumber.get(clazz);
+ Preconditions.checkState(n == null, "Class " + clazz + " already registered to " + n);
+
+ numberToClass.put(number, clazz);
+ classToNumber.put(clazz, number);
+
+ final Object lock = this;
+ return new AbstractRegistration() {
+
+ @Override
+ protected void removeRegistration() {
+ synchronized (lock) {
+ classToNumber.remove(clazz);
+ numberToClass.remove(number);
+ }
+ }
+ };
+ }
+
+ public Class<? extends CLASS> classForFamily(final NUMBER number) {
+ return numberToClass.get(number);
+ }
+
+ public NUMBER numberForClass(final Class<? extends CLASS> clazz) {
+ return classToNumber.get(clazz);
+ }
+}
--- /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;
+
+import org.opendaylight.protocol.bgp.parser.spi.SubsequentAddressFamilyRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateSubsequentAddressFamily;
+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.bgp.types.rev130919.UnicastSubsequentAddressFamily;
+
+import com.google.common.base.Preconditions;
+
+public final class SimpleSubsequentAddressFamilyRegistry implements SubsequentAddressFamilyRegistry {
+ public static final SubsequentAddressFamilyRegistry INSTANCE;
+
+ static {
+ final SubsequentAddressFamilyRegistry reg = new SimpleSubsequentAddressFamilyRegistry();
+
+ reg.registerSubsequentAddressFamily(UnicastSubsequentAddressFamily.class, 1);
+ reg.registerSubsequentAddressFamily(LinkstateSubsequentAddressFamily.class, 71);
+ reg.registerSubsequentAddressFamily(MplsLabeledVpnSubsequentAddressFamily.class, 128);
+
+ INSTANCE = reg;
+ }
+
+ private final SimpleFamilyRegistry<SubsequentAddressFamily, Integer> registry = new SimpleFamilyRegistry<>();
+
+ @Override
+ public AutoCloseable registerSubsequentAddressFamily(final Class<? extends SubsequentAddressFamily> clazz, final int number) {
+ Preconditions.checkArgument(number >= 0 && number <= 255);
+ return registry.registerFamily(clazz, number);
+ }
+
+ @Override
+ public Class<? extends SubsequentAddressFamily> classForFamily(final int number) {
+ return registry.classForFamily(number);
+ }
+
+ @Override
+ public Integer numberForClass(final Class<? extends SubsequentAddressFamily> clazz) {
+ return registry.numberForClass(clazz);
+ }
+}
import com.google.common.base.Preconditions;
public class BGPKeepAliveMessageParser implements MessageParser, MessageSerializer {
- private static final Keepalive msg = new KeepaliveBuilder().build();
- private static final byte[] bytes = MessageUtil.formatMessage(4, new byte[0]);
-
+ public static final int TYPE = 4;
public static final MessageParser PARSER;
public static final MessageSerializer SERIALIZER;
+ private static final Keepalive msg = new KeepaliveBuilder().build();
+ private static final byte[] bytes = MessageUtil.formatMessage(TYPE, new byte[0]);
+
+
static {
final BGPKeepAliveMessageParser p = new BGPKeepAliveMessageParser();
PARSER = p;
* Parser for BGPNotification message.
*/
public final class BGPNotificationMessageParser implements MessageParser, MessageSerializer {
+ public static final int TYPE = 3;
public static final MessageParser PARSER;
public static final MessageSerializer SERIALIZER;
System.arraycopy(ntf.getData(), 0, msgBody, ERROR_SIZE, ntf.getData().length);
}
- final byte[] ret = MessageUtil.formatMessage(3, msgBody);
+ final byte[] ret = MessageUtil.formatMessage(TYPE, msgBody);
logger.trace("Notification message serialized to: {}", Arrays.toString(ret));
return ret;
}
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.open.BGPParameterParser;
+import org.opendaylight.protocol.bgp.parser.impl.message.open.SimpleParameterRegistry;
import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
import org.opendaylight.protocol.bgp.parser.spi.MessageSerializer;
import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterRegistry;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.primitives.UnsignedBytes;
* Parser for BGP Open message.
*/
public final class BGPOpenMessageParser implements MessageParser, MessageSerializer {
+ public static final int TYPE = 1;
public static final MessageParser PARSER;
public static final MessageSerializer SERIALIZER;
static {
- final BGPOpenMessageParser p = new BGPOpenMessageParser();
+ final BGPOpenMessageParser p = new BGPOpenMessageParser(SimpleParameterRegistry.INSTANCE);
PARSER = p;
SERIALIZER = p;
}
private static final int BGP_VERSION = 4;
- private BGPOpenMessageParser() {
+ private final ParameterRegistry reg;
+ private BGPOpenMessageParser(final ParameterRegistry reg) {
+ this.reg = Preconditions.checkNotNull(reg);
}
/**
if (open.getBgpParameters() != null) {
for (final BgpParameters param : open.getBgpParameters()) {
- final byte[] p = BGPParameterParser.put(param);
- optParams.put(p, p.length);
- optParamsLength += p.length;
+ final byte[] p = reg.serializeParameter(param);
+ if (p != null) {
+ optParams.put(p, p.length);
+ optParamsLength += p.length;
+ }
}
}
}
}
- final byte[] ret = MessageUtil.formatMessage(1, msgBody);
+ final byte[] ret = MessageUtil.formatMessage(TYPE, msgBody);
logger.trace("Open message serialized to: {}", Arrays.toString(ret));
return ret;
}
List<BgpParameters> optParams = Lists.newArrayList();
if (optLength > 0) {
+ fillParams(ByteArray.subByte(body, MIN_MSG_LENGTH, optLength), optParams);
+ }
+ logger.trace("Open message was parsed: AS = {}, holdTimer = {}, bgpId = {}, optParams = {}", as, holdTime, bgpId, optParams);
+ return new OpenBuilder().setMyAsNumber(as.getValue().intValue()).setHoldTimer((int) holdTime).setBgpIdentifier(bgpId).setBgpParameters(
+ optParams).build();
+ }
+
+ private void fillParams(final byte[] bytes, final List<BgpParameters> params) throws BGPDocumentedException {
+ if (bytes == null || bytes.length == 0) {
+ throw new IllegalArgumentException("Byte array cannot be null or empty.");
+ }
+
+ logger.trace("Started parsing of BGP parameter: {}", Arrays.toString(bytes));
+ int byteOffset = 0;
+ while (byteOffset < bytes.length) {
+ if (byteOffset + 2 >= bytes.length) {
+ // FIXME: throw a BGPDocumentedException here?
+ throw new IllegalArgumentException("Malformed parameter encountered (" + (bytes.length - byteOffset) + " bytes left)");
+ }
+
+ final int paramType = UnsignedBytes.toInt(bytes[byteOffset++]);
+ final int paramLength = UnsignedBytes.toInt(bytes[byteOffset++]);
+ final byte[] paramBody = ByteArray.subByte(bytes, byteOffset, paramLength);
+ byteOffset += paramLength;
+
+ final BgpParameters param;
try {
- optParams = BGPParameterParser.parse(ByteArray.subByte(body, MIN_MSG_LENGTH, optLength));
+ param = reg.parseParameter(paramType, paramBody);
} catch (final BGPParsingException e) {
throw new BGPDocumentedException("Optional parameter not parsed: ." + e.getMessage(), BGPError.UNSPECIFIC_OPEN_ERROR);
}
+
+ if (param != null) {
+ params.add(param);
+ } else {
+ logger.debug("Ignoring BGP Parameter type: {}", paramType);
+ }
}
- logger.trace("Open message was parsed: AS = {}, holdTimer = {}, bgpId = {}, optParams = {}", as, holdTime, bgpId, optParams);
- return new OpenBuilder().setMyAsNumber(as.getValue().intValue()).setHoldTimer((int) holdTime).setBgpIdentifier(bgpId).setBgpParameters(
- optParams).build();
+
+ logger.trace("Parsed BGP parameters: {}", Arrays.toString(params.toArray()));
}
}
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 BGPUpdateMessageParser PARSER = new BGPUpdateMessageParser();
+ public static final int TYPE = 2;
+ 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
+/*
+ * 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.open;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityParser;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilitySerializer;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityUtil;
+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.open.bgp.parameters.CParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.c.parameters.CAs4Bytes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.c.parameters.CAs4BytesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.c.parameters.c.as4.bytes.As4BytesCapabilityBuilder;
+
+final class As4CapabilityHandler implements CapabilityParser, CapabilitySerializer {
+ static final int CODE = 65;
+
+ @Override
+ public CParameters parseCapability(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
+ return new CAs4BytesBuilder().setAs4BytesCapability(
+ new As4BytesCapabilityBuilder().setAsNumber(new AsNumber(ByteArray.bytesToLong(bytes))).build()).build();
+
+ }
+
+ @Override
+ public byte[] serializeCapability(final CParameters capability) {
+ return CapabilityUtil.formatCapability(CODE, putAS4BytesParameterValue((CAs4Bytes) capability));
+ }
+
+ private static byte[] putAS4BytesParameterValue(final CAs4Bytes param) {
+ return ByteArray.subByte(ByteArray.longToBytes(param.getAs4BytesCapability().getAsNumber().getValue()), 4, 4);
+ }
+}
\ 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.open;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
-import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.util.ByteArray;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParametersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.CParameters;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Lists;
-import com.google.common.primitives.UnsignedBytes;
-
-/**
- * Parser for parameters in BGP Open message.
- */
-public final class BGPParameterParser {
-
- private static final Logger logger = LoggerFactory.getLogger(BGPParameterParser.class);
-
- private static final int TYPE_SIZE = 1; // bytes
- private static final int LENGTH_SIZE = 1; // bytes
- private static final int CAPABILITIES_OPT_PARAM_TYPE = 2;
-
- private BGPParameterParser() {
-
- }
-
- /**
- * Serializes given BGP Parameter to byte array. Currently supported only Capability parameters.
- *
- * @param param BGP Parameter to be serialized
- * @return BGP Parameter converted to byte array
- */
- public static byte[] put(final BgpParameters param) {
- if (param == null) {
- throw new IllegalArgumentException("BGP Parameter cannot be null");
- }
- logger.trace("Started serializing BGPParameter: {}", param);
-
- byte[] value = null;
-
- value = CapabilityParameterParser.put(param.getCParameters());
-
- if (value == null) {
- logger.debug("BGP Parameter not supported.");
- return new byte[] {};
- }
-
- final byte[] bytes = new byte[TYPE_SIZE + LENGTH_SIZE + value.length];
- System.arraycopy(ByteArray.intToBytes(2), 3, bytes, 0, TYPE_SIZE);
- System.arraycopy(ByteArray.intToBytes(value.length), 3, bytes, TYPE_SIZE, LENGTH_SIZE);
- System.arraycopy(value, 0, bytes, TYPE_SIZE + LENGTH_SIZE, value.length);
- logger.trace("BGP Parameter serialized to: {}", Arrays.toString(bytes));
- return bytes;
- }
-
- /**
- * Parses given byte array to a list of BGP Parameters. Currently supporting only Capability parameters.
- *
- * @param bytes byte array representing BGP Parameters
- * @return list of BGP Parameters
- * @throws BGPParsingException if the parsing was unsuccessful
- * @throws BGPDocumentedException
- */
- public static List<BgpParameters> parse(final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
- if (bytes == null || bytes.length == 0) {
- throw new IllegalArgumentException("Byte array cannot be null or empty.");
- }
- logger.trace("Started parsing of BGP parameter: {}", Arrays.toString(bytes));
- int byteOffset = 0;
- final List<BgpParameters> params = Lists.newArrayList();
- while (byteOffset < bytes.length) {
- final int paramType = UnsignedBytes.toInt(bytes[byteOffset++]);
- final int paramLength = UnsignedBytes.toInt(bytes[byteOffset++]);
- if (paramType == CAPABILITIES_OPT_PARAM_TYPE) {
- final CParameters cparam = CapabilityParameterParser.parse(ByteArray.subByte(bytes, byteOffset, paramLength));
- if (cparam == null) {
- byteOffset += paramLength;
- continue;
- }
- final BgpParameters param = new BgpParametersBuilder().setCParameters(cparam).build();
- if (param != null) {
- params.add(param);
- }
- } else {
- logger.debug("BGP Parameter not recognized. Type: {}", paramType);
- }
- byteOffset += paramLength;
- }
- logger.trace("Parsed BGP parameters: {}", Arrays.toString(params.toArray()));
- return params;
- }
-}
import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.bgp.parser.impl.ParserUtil;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterParser;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterUtil;
import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParametersBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.CParameters;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.c.parameters.CAs4Bytes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.open.bgp.parameters.c.parameters.CMultiprotocol;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.open.bgp.parameters.c.parameters.CMultiprotocolBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.open.bgp.parameters.c.parameters.c.multiprotocol.MultiprotocolCapabilityBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedBytes;
/**
* Parser for BGP Capability Parameter.
*/
-public final class CapabilityParameterParser {
+public final class CapabilityParameterParser implements ParameterParser, ParameterSerializer {
+ public static final int TYPE = 2;
private static final Logger logger = LoggerFactory.getLogger(CapabilityParameterParser.class);
+ private final CapabilityRegistry reg;
- private static final int CODE_SIZE = 1; // bytes
- private static final int LENGTH_SIZE = 1; // bytes
- private static final int AFI_SIZE = 2; // bytes
- private static final int SAFI_SIZE = 1; // bytes
-
- private static final int As4BytesCapability_CODE = 65;
- private static final int Multiprotocol_CODE = 1;
-
- private CapabilityParameterParser() {
-
- }
-
- /**
- * Serializes given BGP Capability Parameter to byte array.
- *
- * @param param BGP Capability to be serialized
- * @return BGP Capability converted to byte array
- */
- public static byte[] put(final CParameters cap) {
- if (cap == null) {
- throw new IllegalArgumentException("BGP Capability cannot be null");
- }
- logger.trace("Started serializing BGP Capability: {}", cap);
- byte[] value = null;
- byte[] bytes = null;
- if (cap instanceof CMultiprotocol) {
- value = putMultiProtocolParameterValue((CMultiprotocol) cap);
- bytes = new byte[CODE_SIZE + LENGTH_SIZE + value.length];
- bytes[0] = ByteArray.intToBytes(Multiprotocol_CODE)[Integer.SIZE / Byte.SIZE - 1];
- // } else if (cap instanceof GracefulCapability) {
- // value = putGracefulParameterValue((GracefulCapability) cap);
- } else if (cap instanceof CAs4Bytes) {
- value = putAS4BytesParameterValue((CAs4Bytes) cap);
- bytes = new byte[CODE_SIZE + LENGTH_SIZE + value.length];
- bytes[0] = ByteArray.intToBytes(As4BytesCapability_CODE)[Integer.SIZE / Byte.SIZE - 1];
- }
- if (bytes != null) {
- bytes[1] = ByteArray.intToBytes(value.length)[Integer.SIZE / Byte.SIZE - 1];
- System.arraycopy(value, 0, bytes, CODE_SIZE + LENGTH_SIZE, value.length);
- }
- logger.trace("BGP Parameter serialized to: {}", Arrays.toString(bytes));
- return bytes;
+ public CapabilityParameterParser(final CapabilityRegistry reg) {
+ this.reg = Preconditions.checkNotNull(reg);
}
- /**
- * Parses given byte array to Capability Parameter. Only Multiprotocol capability is supported.
- *
- * @param bytes byte array representing BGP Parameters
- * @return list of BGP Parameters
- * @throws BGPParsingException if the parsing was unsuccessful
- * @throws BGPDocumentedException
- */
- public static CParameters parse(final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
+ @Override
+ public BgpParameters parseParameter(final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
if (bytes == null || bytes.length == 0) {
throw new IllegalArgumentException("Byte array cannot be null or empty.");
}
final int capLength = UnsignedBytes.toInt(bytes[byteOffset++]);
final byte[] paramBody = ByteArray.subByte(bytes, byteOffset, capLength);
- final CParameters ret = SimpleCapabilityRegistry.INSTANCE.parseCapability(capCode, paramBody);
+ final CParameters ret = reg.parseCapability(capCode, paramBody);
if (ret == null) {
logger.debug("Ignoring unsupported capability {}", capCode);
+ return null;
}
- return ret;
- }
- // private static byte[] putGracefulParameterValue(final GracefulCapability param) {
- // final int RESTART_FLAGS_SIZE = 4; // bits
- // final int TIMER_SIZE = 12; // bits
- // final int AFI_SIZE = 2; // bytes
- // final int SAFI_SIZE = 1; // bytes
- // final int AF_FLAGS_SIZE = 1; // bytes
- // final byte[] bytes = new byte[(RESTART_FLAGS_SIZE + TIMER_SIZE + (AFI_SIZE * Byte.SIZE + SAFI_SIZE * Byte.SIZE +
- // AF_FLAGS_SIZE
- // * Byte.SIZE)
- // * param.getTableTypes().size())
- // / Byte.SIZE];
- // if (param.isRestartFlag()) {
- // bytes[0] = (byte) 0x80;
- // }
- // int index = (RESTART_FLAGS_SIZE + TIMER_SIZE) / Byte.SIZE;
- // for (final Entry<BGPTableType, Boolean> entry : param.getTableTypes().entrySet()) {
- // final byte[] a = putAfi(entry.getKey().getAddressFamily());
- // final byte s = putSafi(entry.getKey().getSubsequentAddressFamily());
- // final byte f = (entry.getValue()) ? (byte) 0x80 : (byte) 0x00;
- // System.arraycopy(a, 0, bytes, index, AFI_SIZE);
- // index += AFI_SIZE;
- // bytes[index] = s;
- // index += SAFI_SIZE;
- // bytes[index] = f;
- // index += AF_FLAGS_SIZE;
- // }
- // return bytes;
- // }
-
- private static byte[] putMultiProtocolParameterValue(final CMultiprotocol param) {
- final byte[] a = putAfi(param.getMultiprotocolCapability().getAfi());
- final byte s = putSafi(param.getMultiprotocolCapability().getSafi());
-
- final byte[] bytes = new byte[AFI_SIZE + SAFI_SIZE + 1]; // 2 byte is reserved 2B AFI + 1B Reserved + 1B SAFI
- System.arraycopy(a, 0, bytes, 0, AFI_SIZE);
- bytes[AFI_SIZE + 1] = s; // +1 = reserved
- return bytes;
+ return new BgpParametersBuilder().setCParameters(ret).build();
}
- private static byte[] putAS4BytesParameterValue(final CAs4Bytes param) {
- return ByteArray.subByte(ByteArray.longToBytes(param.getAs4BytesCapability().getAsNumber().getValue()), 4, 4);
- }
+ @Override
+ public byte[] serializeParameter(final BgpParameters parameter) {
+ final CParameters cap = parameter.getCParameters();
- static CMultiprotocol parseMultiProtocolParameterValue(final byte[] bytes) throws BGPParsingException {
- final Class<? extends AddressFamily> afi = ParserUtil.afiForValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, 0, AFI_SIZE)));
- if (afi == null) {
- throw new BGPParsingException("Address Family Identifier: '" + ByteArray.bytesToInt(ByteArray.subByte(bytes, 0, AFI_SIZE))
- + "' not supported.");
- }
- final Class<? extends SubsequentAddressFamily> safi = ParserUtil.safiForValue(ByteArray.bytesToInt(ByteArray.subByte(bytes,
- AFI_SIZE + 1, SAFI_SIZE)));
- if (safi == null) {
- throw new BGPParsingException("Subsequent Address Family Identifier: '"
- + ByteArray.bytesToInt(ByteArray.subByte(bytes, AFI_SIZE + 1, SAFI_SIZE)) + "' not supported.");
- }
+ logger.trace("Started serializing BGP Capability: {}", cap);
- return new CMultiprotocolBuilder().setMultiprotocolCapability(
- new MultiprotocolCapabilityBuilder().setAfi(afi).setSafi(safi).build()).build();
- }
+ byte[] bytes = reg.serializeCapability(cap);
+ if (bytes == null) {
+ throw new IllegalArgumentException("Unhandled capability class" + cap.getImplementedInterface());
+ }
- private static byte[] putAfi(final Class<? extends AddressFamily> afi) {
- final byte[] a = ByteArray.intToBytes(ParserUtil.valueForAfi(afi));
- return ByteArray.subByte(a, Integer.SIZE / Byte.SIZE - AFI_SIZE, AFI_SIZE);
- }
+ logger.trace("BGP capability serialized to: {}", Arrays.toString(bytes));
- private static byte putSafi(final Class<? extends SubsequentAddressFamily> safi) {
- final byte[] a = ByteArray.intToBytes(ParserUtil.valueForSafi(safi));
- return ByteArray.subByte(a, Integer.SIZE / Byte.SIZE - SAFI_SIZE, SAFI_SIZE)[0];
+ return ParameterUtil.formatParameter(TYPE, bytes);
}
}
--- /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.open;
+
+import org.opendaylight.protocol.bgp.parser.spi.CapabilitySerializer;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.CParameters;
+
+final class GracefulCapabilityHandler implements CapabilitySerializer {
+ static final int CODE = 64;
+
+ private static final int RESTART_FLAGS_SIZE = 4; // bits
+ private static final int TIMER_SIZE = 12; // bits
+ private static final int AFI_SIZE = 2; // bytes
+ private static final int SAFI_SIZE = 1; // bytes
+ private static final int AF_FLAGS_SIZE = 1; // bytes
+
+ @Override
+ public byte[] serializeCapability(final CParameters capability) {
+ final byte[] bytes = null;
+
+ // final GracefulCapability param = (GracefulCapability) capability;
+ // final byte[] bytes = new byte[(RESTART_FLAGS_SIZE + TIMER_SIZE + (AFI_SIZE * Byte.SIZE + SAFI_SIZE * Byte.SIZE +
+ // AF_FLAGS_SIZE
+ // * Byte.SIZE)
+ // * param.getTableTypes().size())
+ // / Byte.SIZE];
+ // if (param.isRestartFlag()) {
+ // bytes[0] = (byte) 0x80;
+ // }
+ // int index = (RESTART_FLAGS_SIZE + TIMER_SIZE) / Byte.SIZE;
+ // for (final Entry<BGPTableType, Boolean> entry : param.getTableTypes().entrySet()) {
+ // final byte[] a = putAfi(entry.getKey().getAddressFamily());
+ // final byte s = putSafi(entry.getKey().getSubsequentAddressFamily());
+ // final byte f = (entry.getValue()) ? (byte) 0x80 : (byte) 0x00;
+ // System.arraycopy(a, 0, bytes, index, AFI_SIZE);
+ // index += AFI_SIZE;
+ // bytes[index] = s;
+ // index += SAFI_SIZE;
+ // bytes[index] = f;
+ // index += AF_FLAGS_SIZE;
+ // }
+
+ return CapabilityUtil.formatCapability(CODE, bytes);
+ }
+
+}
--- /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.open;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityParser;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilitySerializer;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityUtil;
+import org.opendaylight.protocol.bgp.parser.spi.SubsequentAddressFamilyRegistry;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.CParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.open.bgp.parameters.c.parameters.CMultiprotocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.open.bgp.parameters.c.parameters.CMultiprotocolBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.open.bgp.parameters.c.parameters.c.multiprotocol.MultiprotocolCapabilityBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.UnsignedBytes;
+
+final class MultiProtocolCapabilityHandler implements CapabilityParser, CapabilitySerializer {
+ static final int CODE = 1;
+
+ private static final int AFI_SIZE = 2; // bytes
+ private static final int SAFI_SIZE = 1; // bytes
+
+ private final AddressFamilyRegistry afiReg;
+ private final SubsequentAddressFamilyRegistry safiReg;
+
+ MultiProtocolCapabilityHandler(final AddressFamilyRegistry afiReg, final SubsequentAddressFamilyRegistry safiReg) {
+ this.afiReg = Preconditions.checkNotNull(afiReg);
+ this.safiReg = Preconditions.checkNotNull(safiReg);
+ }
+
+ @Override
+ public CMultiprotocol parseCapability(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
+ final int afiVal = ByteArray.bytesToInt(ByteArray.subByte(bytes, 0, AFI_SIZE));
+ final Class<? extends AddressFamily> afi = afiReg.classForFamily(afiVal);
+ if (afi == null) {
+ throw new BGPParsingException("Address Family Identifier: '" + afiVal + "' not supported.");
+ }
+
+ final int safiVal = ByteArray.bytesToInt(ByteArray.subByte(bytes, AFI_SIZE + 1, SAFI_SIZE));
+ final Class<? extends SubsequentAddressFamily> safi = safiReg.classForFamily(safiVal);
+ if (safi == null) {
+ throw new BGPParsingException("Subsequent Address Family Identifier: '" + safiVal + "' not supported.");
+ }
+
+ return new CMultiprotocolBuilder().setMultiprotocolCapability(
+ new MultiprotocolCapabilityBuilder().setAfi(afi).setSafi(safi).build()).build();
+ }
+
+ @Override
+ public byte[] serializeCapability(final CParameters capability) {
+ final CMultiprotocol mp = (CMultiprotocol) capability;
+
+ final Class<? extends AddressFamily> afi = mp.getMultiprotocolCapability().getAfi();
+ final Integer afival = afiReg.numberForClass(afi);
+ Preconditions.checkArgument(afival != null, "Unhandled address family " + afi);
+
+ final Class<? extends SubsequentAddressFamily> safi = mp.getMultiprotocolCapability().getSafi();
+ final Integer safival = safiReg.numberForClass(safi);
+ Preconditions.checkArgument(safival != null, "Unhandled subsequent address family " + safi);
+
+ return CapabilityUtil.formatCapability(CODE, new byte[] {
+ UnsignedBytes.checkedCast(afival / 256),
+ UnsignedBytes.checkedCast(afival % 256),
+ 0,
+ UnsignedBytes.checkedCast(safival)
+ });
+ }
+}
\ 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.open;
-
-import org.opendaylight.protocol.bgp.parser.spi.ParameterParser;
-import org.opendaylight.protocol.bgp.parser.spi.ParameterRegistry;
-import org.opendaylight.protocol.bgp.parser.spi.ParameterSerializer;
-import org.opendaylight.protocol.concepts.HandlerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
-
-import com.google.common.base.Preconditions;
-
-public final class ParameterRegistryImpl extends HandlerRegistry<BgpParameters, ParameterParser, ParameterSerializer> implements ParameterRegistry {
- public static final ParameterRegistry INSTANCE;
-
- static {
- final ParameterRegistry reg = new ParameterRegistryImpl();
-
- // FIXME: fix registry
-
- INSTANCE = reg;
- }
-
- @Override
- public AutoCloseable registerParameterParser(final int messageType, final ParameterParser parser) {
- Preconditions.checkArgument(messageType >= 0 && messageType <= 255);
- return super.registerParser(messageType, parser);
- }
-
- @Override
- public ParameterParser getParameterParser(final int messageType) {
- return super.getParser(messageType);
- }
-
- @Override
- public AutoCloseable registerParameterSerializer(final Class<? extends BgpParameters> paramClass, final ParameterSerializer serializer) {
- return super.registerSerializer(paramClass, serializer);
- }
-
- @Override
- public ParameterSerializer getParameterSerializer(final BgpParameters message) {
- return super.getSerializer(message);
- }
-}
import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.impl.SimpleAddressFamilyRegistry;
+import org.opendaylight.protocol.bgp.parser.impl.SimpleSubsequentAddressFamilyRegistry;
import org.opendaylight.protocol.bgp.parser.spi.CapabilityParser;
import org.opendaylight.protocol.bgp.parser.spi.CapabilityRegistry;
import org.opendaylight.protocol.bgp.parser.spi.CapabilitySerializer;
import org.opendaylight.protocol.concepts.HandlerRegistry;
-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.open.bgp.parameters.CParameters;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.c.parameters.CAs4BytesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.c.parameters.c.as4.bytes.As4BytesCapabilityBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.c.parameters.CAs4Bytes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.open.bgp.parameters.c.parameters.CMultiprotocol;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
import com.google.common.base.Preconditions;
static {
final SimpleCapabilityRegistry reg = new SimpleCapabilityRegistry();
- reg.registerCapabilityParser(1, new CapabilityParser() {
- @Override
- public CParameters parseCapability(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
- return CapabilityParameterParser.parseMultiProtocolParameterValue(bytes);
- }
- });
- reg.registerCapabilityParser(65, new CapabilityParser() {
- @Override
- public CParameters parseCapability(final byte[] bytes) throws BGPDocumentedException, BGPParsingException {
- return new CAs4BytesBuilder().setAs4BytesCapability(
- new As4BytesCapabilityBuilder().setAsNumber(new AsNumber(ByteArray.bytesToLong(bytes))).build()).build();
+ final MultiProtocolCapabilityHandler multi =
+ new MultiProtocolCapabilityHandler(SimpleAddressFamilyRegistry.INSTANCE, SimpleSubsequentAddressFamilyRegistry.INSTANCE);
+ reg.registerCapabilityParser(MultiProtocolCapabilityHandler.CODE, multi);
+ reg.registerCapabilitySerializer(CMultiprotocol.class, multi);
- }
- });
+ final As4CapabilityHandler as4 = new As4CapabilityHandler();
+ reg.registerCapabilityParser(As4CapabilityHandler.CODE, as4);
+ reg.registerCapabilitySerializer(CAs4Bytes.class, as4);
INSTANCE = reg;
}
- private final HandlerRegistry<CParameters, CapabilityParser, CapabilitySerializer> handlers = new HandlerRegistry<>();
+ private final HandlerRegistry<DataContainer, CapabilityParser, CapabilitySerializer> handlers = new HandlerRegistry<>();
@Override
public AutoCloseable registerCapabilityParser(final int messageType, final CapabilityParser parser) {
@Override
public byte[] serializeCapability(final CParameters capability) {
- final CapabilitySerializer serializer = handlers.getSerializer(capability);
+ final CapabilitySerializer serializer = handlers.getSerializer(capability.getImplementedInterface());
if (serializer == null) {
return null;
}
--- /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.open;
+
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterParser;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterSerializer;
+import org.opendaylight.protocol.concepts.HandlerRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+import com.google.common.base.Preconditions;
+
+public final class SimpleParameterRegistry implements ParameterRegistry {
+ public static final ParameterRegistry INSTANCE;
+
+ static {
+ final ParameterRegistry reg = new SimpleParameterRegistry();
+
+ final CapabilityParameterParser cpp = new CapabilityParameterParser(SimpleCapabilityRegistry.INSTANCE);
+ reg.registerParameterParser(CapabilityParameterParser.TYPE, cpp);
+ reg.registerParameterSerializer(BgpParameters.class, cpp);
+
+ INSTANCE = reg;
+ }
+
+ private final HandlerRegistry<DataContainer, ParameterParser, ParameterSerializer> handlers = new HandlerRegistry<>();
+
+ @Override
+ public AutoCloseable registerParameterParser(final int messageType, final ParameterParser parser) {
+ Preconditions.checkArgument(messageType >= 0 && messageType <= 255);
+ return handlers.registerParser(messageType, parser);
+ }
+
+ @Override
+ public AutoCloseable registerParameterSerializer(final Class<? extends BgpParameters> paramClass, final ParameterSerializer serializer) {
+ return handlers.registerSerializer(paramClass, serializer);
+ }
+
+ @Override
+ public BgpParameters parseParameter(final int parameterType, final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
+ final ParameterParser parser = handlers.getParser(parameterType);
+ if (parser == null) {
+ return null;
+ }
+
+ return parser.parseParameter(bytes);
+ }
+
+ @Override
+ public byte[] serializeParameter(final BgpParameters parameter) {
+ final ParameterSerializer serializer = handlers.getSerializer(parameter.getImplementedInterface());
+ if (serializer == null) {
+ return null;
+ }
+
+ return serializer.serializeParameter(parameter);
+ }
+}
--- /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
--- /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 org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
+import org.opendaylight.protocol.bgp.parser.spi.NlriUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+
+abstract class IpNlriParser implements NlriParser {
+ protected abstract DestinationType parseNlri(final byte[] nlri);
+
+ @Override
+ public final void parseNlri(final byte[] nlri, final MpUnreachNlriBuilder builder) {
+ builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(parseNlri(nlri)).build());
+ }
+
+ @Override
+ public final void parseNlri(final byte[] nlri, final byte[] nextHop, final MpReachNlriBuilder builder) throws BGPParsingException {
+ builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(parseNlri(nlri)).build());
+ NlriUtil.parseNextHop(nextHop, builder);
+ }
+}
\ 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 org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.destination.type.DestinationIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.destination.type.DestinationIpv4Builder;
+
+final class Ipv4NlriParser extends IpNlriParser {
+ @Override
+ protected DestinationIpv4 parseNlri(final byte[] nlri) {
+ return new DestinationIpv4Builder().setIpv4Prefixes(Ipv4Util.prefixListForBytes(nlri)).build();
+ }
+}
\ 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 org.opendaylight.protocol.concepts.Ipv6Util;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.destination.type.DestinationIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.destination.type.DestinationIpv6Builder;
+
+final class Ipv6NlriParser extends IpNlriParser {
+ @Override
+ protected DestinationIpv6 parseNlri(final byte[] nlri) {
+ return new DestinationIpv6Builder().setIpv6Prefixes(Ipv6Util.prefixListForBytes(nlri)).build();
+ }
+}
\ 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.math.BigInteger;
+import java.util.Arrays;
+
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
+import org.opendaylight.protocol.bgp.parser.spi.NlriUtil;
+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.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.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.AreaIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.DomainIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Identifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv4InterfaceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv6InterfaceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NlriType;
+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.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.TopologyIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.RemoteNodeDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.CRouterIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.node.IsisNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.pseudonode.IsisPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.node.OspfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.pseudonode.OspfPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.IsoSystemIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.primitives.UnsignedBytes;
+
+final class LinkstateNlriParser implements NlriParser {
+ private static final Logger logger = LoggerFactory.getLogger(LinkstateNlriParser.class);
+ private static final int ROUTE_DISTINGUISHER_LENGTH = 8;
+ private static final int PROTOCOL_ID_LENGTH = 1;
+ private static final int IDENTIFIER_LENGTH = 8;
+
+ private static final int TYPE_LENGTH = 2;
+ private static final int LENGTH_SIZE = 2;
+
+ private final boolean isVpn;
+
+ public LinkstateNlriParser(final boolean isVpn) {
+ this.isVpn = isVpn;
+ }
+
+ private static NodeIdentifier parseLink(final CLinkstateDestinationBuilder builder, final byte[] bytes) throws BGPParsingException {
+ int byteOffset = 0;
+ final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
+ byteOffset += TYPE_LENGTH;
+ final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
+ byteOffset += LENGTH_SIZE;
+ final NodeIdentifier remote = null;
+ if (type == 257) {
+ builder.setRemoteNodeDescriptors((RemoteNodeDescriptors) parseNodeDescriptors(ByteArray.subByte(bytes, byteOffset, length)));
+ byteOffset += length;
+ }
+ builder.setLinkDescriptors(parseLinkDescriptors(ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset)));
+ return remote;
+ }
+
+ private static LinkDescriptors parseLinkDescriptors(final byte[] bytes) throws BGPParsingException {
+ int byteOffset = 0;
+ final LinkDescriptorsBuilder builder = new LinkDescriptorsBuilder();
+ while (byteOffset != bytes.length) {
+ final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
+ byteOffset += TYPE_LENGTH;
+ final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
+ byteOffset += LENGTH_SIZE;
+ final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
+ logger.debug("Parsing Link Descriptor: {}", Arrays.toString(value));
+ switch (type) {
+ case 258:
+ builder.setLinkLocalIdentifier(ByteArray.subByte(value, 0, 4));
+ builder.setLinkRemoteIdentifier(ByteArray.subByte(value, 4, 4));
+ logger.trace("Parsed link local {} remote {} Identifiers.", builder.getLinkLocalIdentifier(),
+ builder.getLinkRemoteIdentifier());
+ break;
+ case 259:
+ final Ipv4InterfaceIdentifier lipv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
+ builder.setIpv4InterfaceAddress(lipv4);
+ logger.trace("Parsed IPv4 interface address {}.", lipv4);
+ break;
+ case 260:
+ final Ipv4InterfaceIdentifier ripv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
+ builder.setIpv4NeighborAddress(ripv4);
+ logger.trace("Parsed IPv4 neighbor address {}.", ripv4);
+ break;
+ case 261:
+ final Ipv6InterfaceIdentifier lipv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
+ builder.setIpv6InterfaceAddress(lipv6);
+ logger.trace("Parsed IPv6 interface address {}.", lipv6);
+ break;
+ case 262:
+ final Ipv6InterfaceIdentifier ripv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
+ builder.setIpv6NeighborAddress(ripv6);
+ logger.trace("Parsed IPv6 neighbor address {}.", ripv6);
+ break;
+ case 263:
+ final TopologyIdentifier topId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
+ builder.setMultiTopologyId(topId);
+ logger.trace("Parsed topology identifier {}.", topId);
+ break;
+ default:
+ throw new BGPParsingException("Link Descriptor not recognized, type: " + type);
+ }
+ byteOffset += length;
+ }
+ logger.debug("Finished parsing Link descriptors.");
+ return builder.build();
+ }
+
+ private static NodeIdentifier parseNodeDescriptors(final byte[] bytes) throws BGPParsingException {
+ int byteOffset = 0;
+ AsNumber asnumber = null;
+ DomainIdentifier bgpId = null;
+ AreaIdentifier ai = null;
+ CRouterIdentifier routerId = null;
+ while (byteOffset != bytes.length) {
+ final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
+ byteOffset += TYPE_LENGTH;
+ final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
+ byteOffset += LENGTH_SIZE;
+ final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
+ logger.debug("Parsing Node Descriptor: {}", Arrays.toString(value));
+ switch (type) {
+ case 512:
+ asnumber = new AsNumber(ByteArray.bytesToLong(value));
+ logger.trace("Parsed AS number {}", asnumber);
+ break;
+ case 513:
+ bgpId = new DomainIdentifier(value);
+ logger.trace("Parsed bgpId {}", bgpId);
+ break;
+ case 514:
+ ai = new AreaIdentifier(value);
+ logger.trace("Parsed area identifier {}", ai);
+ break;
+ case 515:
+ if (value.length == 6) {
+ routerId = new CIsisNodeBuilder().setIsisNode(
+ new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
+ } else if (value.length == 7) {
+ if (value[6] == 0) {
+ logger.warn("PSN octet is 0. Ignoring System ID.");
+ routerId = new CIsisNodeBuilder().setIsisNode(
+ new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
+ break;
+ } else {
+ final IsIsRouterIdentifier iri = new IsIsRouterIdentifierBuilder().setIsoSystemId(
+ new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build();
+ routerId = new CIsisPseudonodeBuilder().setIsisPseudonode(
+ new IsisPseudonodeBuilder().setIsIsRouterIdentifier(iri).setPsn((short) UnsignedBytes.toInt(value[6])).build()).build();
+ }
+ } else if (value.length == 4) {
+ routerId = new COspfNodeBuilder().setOspfNode(
+ new OspfNodeBuilder().setOspfRouterId(ByteArray.subByte(value, 0, 4)).build()).build();
+ } else if (value.length == 8) {
+ final byte[] o = ByteArray.subByte(value, 0, 4); // FIXME: OSPFv3 vs OSPFv2
+ final OspfInterfaceIdentifier a = new OspfInterfaceIdentifier(ByteArray.subByte(value, 4, 4));
+ routerId = new COspfPseudonodeBuilder().setOspfPseudonode(
+ new OspfPseudonodeBuilder().setOspfRouterId(o).setLanInterface(a).build()).build();
+ }
+ logger.trace("Parsed Router Identifier {}", routerId);
+ break;
+ default:
+ throw new BGPParsingException("Node Descriptor not recognized, type: " + type);
+ }
+ byteOffset += length;
+ }
+ logger.debug("Finished parsing Node descriptors.");
+ return new LocalNodeDescriptorsBuilder().setAsNumber(asnumber).setDomainId(bgpId).setAreaId(ai).setCRouterIdentifier(routerId).build();
+ }
+
+ private static PrefixDescriptors parsePrefixDescriptors(final NodeIdentifier localDescriptor, final byte[] bytes) throws BGPParsingException {
+ int byteOffset = 0;
+ final PrefixDescriptorsBuilder builder = new PrefixDescriptorsBuilder();
+ while (byteOffset != bytes.length) {
+ final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
+ byteOffset += TYPE_LENGTH;
+ final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
+ byteOffset += LENGTH_SIZE;
+ final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
+ logger.trace("Parsing Prefix Descriptor: {}", Arrays.toString(value));
+ switch (type) {
+ case 263:
+ final TopologyIdentifier topologyId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
+ builder.setMultiTopologyId(topologyId);
+ logger.trace("Parsed Topology Identifier: {}", topologyId);
+ break;
+ case 264:
+ final int rt = ByteArray.bytesToInt(value);
+ final OspfRouteType routeType = OspfRouteType.forValue(rt);
+ if (routeType == null) {
+ throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
+ }
+ builder.setOspfRouteType(routeType);
+ logger.trace("Parser RouteType: {}", routeType);
+ break;
+ case 265:
+ IpPrefix prefix = null;
+ final int prefixLength = UnsignedBytes.toInt(value[0]);
+ final int size = prefixLength / 8 + ((prefixLength % 8 == 0) ? 0 : 1);
+ if (size != value.length - 1) {
+ 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) {
+ prefix = new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
+ } else {
+ prefix = new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
+ }
+ builder.setIpReachabilityInformation(prefix);
+ logger.trace("Parsed IP reachability info: {}", prefix);
+ break;
+ default:
+ throw new BGPParsingException("Prefix Descriptor not recognized, type: " + type);
+ }
+ byteOffset += length;
+ }
+ logger.debug("Finished parsing Prefix descriptors.");
+ return builder.build();
+ }
+
+ /**
+ * Parses common parts for Link State Nodes, Links and Prefixes, that includes protocol ID and identifier tlv.
+ *
+ * @param nlri
+ * @return BGPLinkMP or BGPNodeMP
+ * @throws BGPParsingException
+ */
+ private final CLinkstateDestination parseNlri(final byte[] nlri) throws BGPParsingException {
+ if (nlri.length == 0) {
+ return null;
+ }
+ int byteOffset = 0;
+
+ final CLinkstateDestinationBuilder builder = new CLinkstateDestinationBuilder();
+
+ while (byteOffset != nlri.length) {
+ final NlriType type = NlriType.forValue(ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, TYPE_LENGTH)));
+ builder.setNlriType(type);
+
+ byteOffset += TYPE_LENGTH;
+ // length means total length of the tlvs including route distinguisher not including the type field
+ final int length = ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, LENGTH_SIZE));
+ byteOffset += LENGTH_SIZE;
+ RouteDistinguisher distinguisher = null;
+ if (isVpn) {
+ // this parses route distinguisher
+ distinguisher = new RouteDistinguisher(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(nlri, byteOffset,
+ ROUTE_DISTINGUISHER_LENGTH))));
+ builder.setDistinguisher(distinguisher);
+ byteOffset += ROUTE_DISTINGUISHER_LENGTH;
+ }
+ // parse source protocol
+ final ProtocolId sp = ProtocolId.forValue(ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, PROTOCOL_ID_LENGTH)));
+ byteOffset += PROTOCOL_ID_LENGTH;
+ builder.setProtocolId(sp);
+
+ // parse identifier
+ final Identifier identifier = new Identifier(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(nlri, byteOffset,
+ IDENTIFIER_LENGTH))));
+ byteOffset += IDENTIFIER_LENGTH;
+ builder.setIdentifier(identifier);
+
+ // if we are dealing with linkstate nodes/links, parse local node descriptor
+ NodeIdentifier localDescriptor = null;
+ int locallength = 0;
+ final int localtype = ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, TYPE_LENGTH));
+ byteOffset += TYPE_LENGTH;
+ locallength = ByteArray.bytesToInt(ByteArray.subByte(nlri, byteOffset, LENGTH_SIZE));
+ byteOffset += LENGTH_SIZE;
+ if (localtype == 256) {
+ localDescriptor = parseNodeDescriptors(ByteArray.subByte(nlri, byteOffset, locallength));
+ }
+ byteOffset += locallength;
+ builder.setLocalNodeDescriptors((LocalNodeDescriptors) localDescriptor);
+ final int restLength = length - (isVpn ? ROUTE_DISTINGUISHER_LENGTH : 0)
+ - PROTOCOL_ID_LENGTH - IDENTIFIER_LENGTH - TYPE_LENGTH - LENGTH_SIZE - locallength;
+ logger.debug("Restlength {}", restLength);
+ switch (type) {
+ case Link:
+ parseLink(builder, ByteArray.subByte(nlri, byteOffset, restLength));
+ break;
+ case Ipv4Prefix:
+ case Ipv6Prefix:
+ builder.setPrefixDescriptors(parsePrefixDescriptors(localDescriptor, ByteArray.subByte(nlri, byteOffset, restLength)));
+ break;
+ case Node:
+ // node nlri is already parsed as it contains only the common fields for node and link nlri
+ break;
+ }
+ byteOffset += restLength;
+ }
+ return builder.build();
+ }
+
+ @Override
+ public final void parseNlri(final byte[] nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException {
+ final CLinkstateDestination dst = parseNlri(nlri);
+
+ // FIXME: This cast is because of a bug in yangtools (augmented choice has no relationship with base choice)
+ final DestinationType s = (DestinationType)new DestinationLinkstateBuilder().setCLinkstateDestination(dst).build();
+
+ builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(s).build());
+ }
+
+ @Override
+ public final void parseNlri(final byte[] nlri, final byte[] nextHop, final MpReachNlriBuilder builder) throws BGPParsingException {
+ final CLinkstateDestination dst = parseNlri(nlri);
+
+ // FIXME: This cast is because of a bug in yangtools (augmented choice has no relationship with base choice)
+ final DestinationType s = (DestinationType)new DestinationLinkstateBuilder().setCLinkstateDestination(dst).build();
+
+ builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(s).build());
+ NlriUtil.parseNextHop(nextHop, builder);
+ }
+}
\ 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.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.protocol.bgp.parser.spi.NlriRegistry;
+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;
+
+import com.google.common.base.Preconditions;
+
+final class MPReachAttributeParser implements AttributeParser {
+ static final int TYPE = 14;
+
+ private final NlriRegistry reg;
+
+ MPReachAttributeParser(final NlriRegistry reg) {
+ this.reg = Preconditions.checkNotNull(reg);
+ }
+
+ @Override
+ public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
+ try {
+ final PathAttributes1 a = new PathAttributes1Builder().setMpReachNlri(reg.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
+++ /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.BGPParsingException;
-import org.opendaylight.protocol.bgp.parser.impl.ParserUtil;
-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.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.nlri.LinkstateBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.AdvertizedRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.Nlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.nlri.Ipv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.nlri.Ipv6Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.WithdrawnRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
-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.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.CIpv6NextHopBuilder;
-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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.c.ipv6.next.hop.Ipv6NextHopBuilder;
-
-import com.google.common.primitives.UnsignedBytes;
-
-/**
- * Parser for MP_REACH or MP_UNREACH fields.
- */
-public class MPReachParser {
-
- private static final int ADDRESS_FAMILY_IDENTIFIER_SIZE = 2;
-
- private static final int SUBSEQUENT_ADDRESS_FAMILY_IDENTIFIER_SIZE = 1;
-
- private static final int NEXT_HOP_LENGTH_SIZE = 1;
-
- private static final int RESERVED_SIZE = 1;
-
- private MPReachParser() {
-
- }
-
- static MpUnreachNlri parseMPUnreach(final byte[] bytes) throws BGPParsingException {
- int byteOffset = 0;
- final MpUnreachNlriBuilder builder = new MpUnreachNlriBuilder();
- final Class<? extends AddressFamily> afi = ParserUtil.afiForValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset,
- ADDRESS_FAMILY_IDENTIFIER_SIZE)));
- if (afi == null) {
- throw new BGPParsingException("Address Family Identifier: '"
- + ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, ADDRESS_FAMILY_IDENTIFIER_SIZE)) + "' not supported.");
- }
- byteOffset += ADDRESS_FAMILY_IDENTIFIER_SIZE;
- builder.setAfi(afi);
-
- final Class<? extends SubsequentAddressFamily> safi = ParserUtil.safiForValue(UnsignedBytes.toInt(bytes[byteOffset]));
- if (safi == null) {
- throw new BGPParsingException("Subsequent Address Family Identifier: '" + UnsignedBytes.toInt(bytes[byteOffset])
- + "' not supported.");
- }
- byteOffset += SUBSEQUENT_ADDRESS_FAMILY_IDENTIFIER_SIZE;
- builder.setSafi(safi);
-
- final WithdrawnRoutes routes = new WithdrawnRoutesBuilder().setNlri(
- (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.Nlri) chooseReachParser(
- afi, safi, ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset))).build();
- builder.setWithdrawnRoutes(routes);
- return builder.build();
- }
-
- static MpReachNlri parseMPReach(final byte[] bytes) throws BGPParsingException {
- int byteOffset = 0;
- final MpReachNlriBuilder builder = new MpReachNlriBuilder();
- final Class<? extends AddressFamily> afi = ParserUtil.afiForValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset,
- ADDRESS_FAMILY_IDENTIFIER_SIZE)));
- if (afi == null) {
- throw new BGPParsingException("Address Family Identifier: '"
- + ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, ADDRESS_FAMILY_IDENTIFIER_SIZE)) + "' not supported.");
- }
- byteOffset += ADDRESS_FAMILY_IDENTIFIER_SIZE;
- builder.setAfi(afi);
-
- final Class<? extends SubsequentAddressFamily> safi = ParserUtil.safiForValue(UnsignedBytes.toInt(bytes[byteOffset]));
- if (safi == null) {
- throw new BGPParsingException("Subsequent Address Family Identifier: '" + UnsignedBytes.toInt(bytes[byteOffset])
- + "' not supported.");
- }
- byteOffset += SUBSEQUENT_ADDRESS_FAMILY_IDENTIFIER_SIZE;
- builder.setSafi(safi);
-
- final int nextHopLength = UnsignedBytes.toInt(bytes[byteOffset]);
- byteOffset += NEXT_HOP_LENGTH_SIZE;
- final CNextHop nextHop = parseNextHop(ByteArray.subByte(bytes, byteOffset, nextHopLength));
- byteOffset += nextHopLength + RESERVED_SIZE;
- builder.setCNextHop(nextHop);
-
- final AdvertizedRoutes routes = new AdvertizedRoutesBuilder().setNlri(
- (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.destination.Nlri) chooseReachParser(
- afi, safi, ByteArray.subByte(bytes, byteOffset, bytes.length - (byteOffset)))).build();
- builder.setAdvertizedRoutes(routes);
- return builder.build();
- }
-
- private static Nlri chooseReachParser(final Class<? extends AddressFamily> afi, final Class<? extends SubsequentAddressFamily> safi,
- final byte[] bytes) throws BGPParsingException {
- if (afi == Ipv4AddressFamily.class) {
- final List<Ipv4Prefix> nlri4 = Ipv4Util.prefixListForBytes(bytes);
- return new Ipv4Builder().setIpv4Prefixes(nlri4).build();
- } else if (afi == Ipv6AddressFamily.class) {
- 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 null;
- }
-
- private static CNextHop parseNextHop(final byte[] bytes) throws BGPParsingException {
- final CNextHop addr;
- switch (bytes.length) {
- case 4:
- addr = new CIpv4NextHopBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(Ipv4Util.addressForBytes(bytes)).build()).build();
- break;
- case 16:
- addr = new CIpv6NextHopBuilder().setIpv6NextHop(new Ipv6NextHopBuilder().setGlobal(Ipv6Util.addressForBytes(bytes)).build()).build();
- break;
- case 32:
- addr = new CIpv6NextHopBuilder().setIpv6NextHop(
- new Ipv6NextHopBuilder().setGlobal(Ipv6Util.addressForBytes(ByteArray.subByte(bytes, 0, 16))).setLinkLocal(
- Ipv6Util.addressForBytes(ByteArray.subByte(bytes, 16, 16))).build()).build();
- break;
- default:
- throw new BGPParsingException("Cannot parse NEXT_HOP attribute. Wrong bytes length: " + bytes.length);
- }
- return addr;
- }
-}
--- /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.protocol.bgp.parser.spi.NlriRegistry;
+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 com.google.common.base.Preconditions;
+
+final class MPUnreachAttributeParser implements AttributeParser {
+ static final int TYPE = 15;
+
+ private final NlriRegistry reg;
+
+ MPUnreachAttributeParser(final NlriRegistry reg) {
+ this.reg = Preconditions.checkNotNull(reg);
+ }
+
+ @Override
+ public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPDocumentedException {
+ try {
+ final PathAttributes2 a = new PathAttributes2Builder().setMpUnreachNlri(reg.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.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 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 = SimpleAttributeRegistry.INSTANCE.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.linkstate.LinkstateAttributeParser;
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(SimpleNlriRegistry.INSTANCE));
+ reg.registerAttributeParser(MPUnreachAttributeParser.TYPE, new MPUnreachAttributeParser(SimpleNlriRegistry.INSTANCE));
+ 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<DataObject, AttributeParser, AttributeSerializer> handlers = new HandlerRegistry<>();
+ 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
public byte[] serializeAttribute(final DataObject attribute) {
- final AttributeSerializer serializer = handlers.getSerializer(attribute);
+ final AttributeSerializer serializer = handlers.getSerializer(attribute.getImplementedInterface());
if (serializer == null) {
return null;
}
--- /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.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.protocol.bgp.parser.impl.SimpleAddressFamilyRegistry;
+import org.opendaylight.protocol.bgp.parser.impl.SimpleSubsequentAddressFamilyRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
+import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.SubsequentAddressFamilyRegistry;
+import org.opendaylight.protocol.concepts.AbstractRegistration;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+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.bgp.types.rev130919.UnicastSubsequentAddressFamily;
+
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.UnsignedBytes;
+
+public final class SimpleNlriRegistry implements NlriRegistry {
+ public static final NlriRegistry INSTANCE;
+
+ static {
+ final NlriRegistry reg = new SimpleNlriRegistry(SimpleAddressFamilyRegistry.INSTANCE,
+ SimpleSubsequentAddressFamilyRegistry.INSTANCE);
+
+ final NlriParser ipv4 = new Ipv4NlriParser();
+ reg.registerNlriParser(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, ipv4);
+
+ final NlriParser ipv6 = new Ipv6NlriParser();
+ reg.registerNlriParser(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, ipv6);
+
+ reg.registerNlriParser(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class, new LinkstateNlriParser(false));
+ reg.registerNlriParser(LinkstateAddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class, new LinkstateNlriParser(true));
+
+ INSTANCE = reg;
+ }
+
+ private static BgpTableType createKey(final Class<? extends AddressFamily> afi,
+ final Class<? extends SubsequentAddressFamily> safi) {
+ Preconditions.checkNotNull(afi);
+ Preconditions.checkNotNull(safi);
+ return new BgpTableTypeImpl(afi, safi);
+ }
+
+ private final ConcurrentMap<BgpTableType, NlriParser> handlers = new ConcurrentHashMap<>();
+ private final SubsequentAddressFamilyRegistry safiReg;
+ private final AddressFamilyRegistry afiReg;
+
+ public SimpleNlriRegistry(final AddressFamilyRegistry afiReg, final SubsequentAddressFamilyRegistry safiReg) {
+ this.afiReg = Preconditions.checkNotNull(afiReg);
+ this.safiReg = Preconditions.checkNotNull(safiReg);
+ }
+
+ @Override
+ public synchronized AutoCloseable registerNlriParser(final Class<? extends AddressFamily> afi,
+ final Class<? extends SubsequentAddressFamily> safi, final NlriParser parser) {
+ final BgpTableType key = createKey(afi, safi);
+ final NlriParser prev = handlers.get(key);
+ Preconditions.checkState(prev == null, "AFI/SAFI is already bound to parser " + prev);
+
+ handlers.put(key, parser);
+ final Object lock = this;
+ return new AbstractRegistration() {
+ @Override
+ protected void removeRegistration() {
+ synchronized (lock) {
+ handlers.remove(key);
+ }
+ }
+ };
+ }
+
+ private Class<? extends AddressFamily> getAfi(final byte[] header) throws BGPParsingException {
+ final int afiVal = UnsignedBytes.toInt(header[0]) * 256 + UnsignedBytes.toInt(header[1]);
+ final Class<? extends AddressFamily> afi = afiReg.classForFamily(afiVal);
+ if (afi == null) {
+ throw new BGPParsingException("Address Family Identifier: '" + afiVal + "' not supported.");
+ }
+
+ return afi;
+ }
+
+ private Class<? extends SubsequentAddressFamily> getSafi(final byte[] header) throws BGPParsingException {
+ final int safiVal = UnsignedBytes.toInt(header[2]);
+ final Class<? extends SubsequentAddressFamily> safi = safiReg.classForFamily(safiVal);
+ if (safi == null) {
+ throw new BGPParsingException("Subsequent Address Family Identifier: '" + safiVal + "' not supported.");
+ }
+
+ return safi;
+ }
+
+ @Override
+ public MpUnreachNlri parseMpUnreach(final byte[] bytes) throws BGPParsingException {
+ final MpUnreachNlriBuilder builder = new MpUnreachNlriBuilder();
+ builder.setAfi(getAfi(bytes));
+ builder.setSafi(getSafi(bytes));
+
+ final NlriParser parser = handlers.get(createKey(builder.getAfi(), builder.getSafi()));
+ parser.parseNlri(ByteArray.subByte(bytes, 3, bytes.length - 3), builder);
+
+ // builder.setWithdrawnRoutes(routes);
+ return builder.build();
+ }
+
+ @Override
+ public MpReachNlri parseMpReach(final byte[] bytes) throws BGPParsingException {
+ final MpReachNlriBuilder builder = new MpReachNlriBuilder();
+ builder.setAfi(getAfi(bytes));
+ builder.setSafi(getSafi(bytes));
+
+ final NlriParser parser = handlers.get(createKey(builder.getAfi(), builder.getSafi()));
+
+ final int nextHopLength = UnsignedBytes.toInt(bytes[3]);
+ int byteOffset = 4;
+
+ final byte[] nextHop = ByteArray.subByte(bytes, byteOffset, nextHopLength);
+ byteOffset += nextHopLength + 1;
+
+ final byte[] nlri = ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset);
+ parser.parseNlri(nlri, nextHop, builder);
+
+ return builder.build();
+ }
+}
import org.opendaylight.protocol.bgp.parser.impl.message.update.CommunitiesParser;
import org.opendaylight.protocol.framework.DeserializerException;
import org.opendaylight.protocol.framework.DocumentedException;
+import org.opendaylight.protocol.util.ByteList;
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.LinkstateAddressFamily;
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());
--- /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.spi;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+
+public interface AddressFamilyRegistry {
+ public AutoCloseable registerAddressFamily(Class<? extends AddressFamily> clazz, int number);
+
+ public Class<? extends AddressFamily> classForFamily(int number);
+ public Integer numberForClass(Class<? extends AddressFamily> clazz);
+}
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);
}
--- /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.spi;
+
+import org.opendaylight.protocol.util.ByteArray;
+
+import com.google.common.primitives.UnsignedBytes;
+
+public final class CapabilityUtil {
+
+ public static final int CODE_SIZE = 1; // bytes
+ public static final int LENGTH_SIZE = 1; // bytes
+ private static final int HEADER_SIZE = CODE_SIZE + LENGTH_SIZE;
+
+ private CapabilityUtil() {
+
+ }
+
+ public static byte[] formatCapability(final int code, final byte[] value) {
+ final byte[] ret = new byte[HEADER_SIZE + value.length];
+ ret[0] = UnsignedBytes.checkedCast(code);
+ ret[1] = UnsignedBytes.checkedCast(value.length);
+ ByteArray.copyWhole(value, ret, HEADER_SIZE);
+ return ret;
+ }
+}
--- /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.spi;
+
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlriBuilder;
+
+public interface NlriParser {
+ public void parseNlri(byte[] nlri, MpUnreachNlriBuilder builder) throws BGPParsingException;
+ public void parseNlri(byte[] nlri, byte[] nextHop, MpReachNlriBuilder builder) throws BGPParsingException;
+}
--- /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.spi;
+
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+
+public interface NlriRegistry {
+ public AutoCloseable registerNlriParser(Class<? extends AddressFamily> afi,
+ Class<? extends SubsequentAddressFamily> safi, NlriParser parser);
+ // public AutoCloseable registerNlriSerializer(Class<? extends DataObject> nlriClass, NlriSerializer serializer);
+
+ public MpUnreachNlri parseMpUnreach(final byte[] bytes) throws BGPParsingException;
+ public MpReachNlri parseMpReach(final byte[] bytes) throws BGPParsingException;
+ // public byte[] serializeNlri(DataObject attribute);
+}
--- /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.spi;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public interface NlriSerializer {
+ public byte[] serializeAttribute(final DataObject attribute);
+}
--- /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.spi;
+
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+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.multiprotocol.rev130918.update.path.attributes.MpReachNlriBuilder;
+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.CIpv6NextHopBuilder;
+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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.c.ipv6.next.hop.Ipv6NextHopBuilder;
+
+public final class NlriUtil {
+ private NlriUtil() {
+
+ }
+
+ public static void parseNextHop(final byte[] bytes, final MpReachNlriBuilder builder) throws BGPParsingException {
+ final CNextHop addr;
+
+ switch (bytes.length) {
+ case 4:
+ addr = new CIpv4NextHopBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(Ipv4Util.addressForBytes(bytes)).build()).build();
+ break;
+ case 16:
+ addr = new CIpv6NextHopBuilder().setIpv6NextHop(new Ipv6NextHopBuilder().setGlobal(Ipv6Util.addressForBytes(bytes)).build()).build();
+ break;
+ case 32:
+ addr = new CIpv6NextHopBuilder().setIpv6NextHop(
+ new Ipv6NextHopBuilder().setGlobal(Ipv6Util.addressForBytes(ByteArray.subByte(bytes, 0, 16))).setLinkLocal(
+ Ipv6Util.addressForBytes(ByteArray.subByte(bytes, 16, 16))).build()).build();
+ break;
+ default:
+ throw new BGPParsingException("Cannot parse NEXT_HOP attribute. Wrong bytes length: " + bytes.length);
+ }
+
+ builder.setCNextHop(addr);
+ }
+}
*/
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.open.BgpParameters;
public interface ParameterParser {
- public BgpParameters parseParameter(final byte[] bytes) throws BGPParsingException;
+ public BgpParameters parseParameter(final byte[] bytes) throws BGPParsingException, BGPDocumentedException;
}
*/
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.open.BgpParameters;
public interface ParameterRegistry {
public AutoCloseable registerParameterParser(int parameterType, ParameterParser parser);
- public ParameterParser getParameterParser(int parameterType);
-
public AutoCloseable registerParameterSerializer(Class<? extends BgpParameters> paramClass, ParameterSerializer serializer);
- public ParameterSerializer getParameterSerializer(BgpParameters object);
+
+ public BgpParameters parseParameter(int parameterType, final byte[] bytes) throws BGPParsingException, BGPDocumentedException;
+ public byte[] serializeParameter(final BgpParameters parameter);
}
--- /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.spi;
+
+import com.google.common.primitives.UnsignedBytes;
+
+public final class ParameterUtil {
+ private ParameterUtil() {
+
+ }
+
+ public static byte[] formatParameter(final int type, final byte[] value) {
+ final byte[] bytes = new byte[2 + value.length];
+ bytes[0] = UnsignedBytes.checkedCast(type);
+ bytes[1] = UnsignedBytes.checkedCast(value.length);
+ System.arraycopy(value, 0, bytes, 2, value.length);
+ return bytes;
+ }
+}
--- /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.spi;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+
+public interface SubsequentAddressFamilyRegistry {
+ public AutoCloseable registerSubsequentAddressFamily(Class<? extends SubsequentAddressFamily> clazz, int number);
+
+ public Class<? extends SubsequentAddressFamily> classForFamily(int number);
+ public Integer numberForClass(Class<? extends SubsequentAddressFamily> clazz);
+}
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction ;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.protocol.bgp.rib.spi.AbstractAdjRIBsIn;
import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsInFactory;
}
};
- for (Ipv4Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.withdrawn.routes.nlri.Ipv4)nlri.getAdvertizedRoutes().getNlri()).getIpv4Prefixes()) {
+ for (Ipv4Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationIpv4)nlri.getAdvertizedRoutes().getDestinationType()).getIpv4Prefixes()) {
super.add(trans, peer, id, data);
}
}
@Override
public void removeRoutes(final DataModificationTransaction trans, final Peer peer,
final MpUnreachNlri nlri) {
- for (Ipv4Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.withdrawn.routes.nlri.Ipv4)nlri.getWithdrawnRoutes().getNlri()).getIpv4Prefixes()) {
+ for (Ipv4Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationIpv4)nlri.getWithdrawnRoutes().getDestinationType()).getIpv4Prefixes()) {
super.remove(trans, peer, id);
}
}
}
};
- for (Ipv6Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.nlri.Ipv6)nlri.getAdvertizedRoutes().getNlri()).getIpv6Prefixes()) {
+ for (Ipv6Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv6)nlri.getAdvertizedRoutes().getDestinationType()).getIpv6Prefixes()) {
super.add(trans, peer, id, data);
}
}
@Override
public void removeRoutes(final DataModificationTransaction trans, final Peer peer,
final MpUnreachNlri nlri) {
- for (Ipv6Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.withdrawn.routes.nlri.Ipv6)nlri.getWithdrawnRoutes().getNlri()).getIpv6Prefixes()) {
+ for (Ipv6Prefix id : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130918.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationIpv6)nlri.getWithdrawnRoutes().getDestinationType()).getIpv6Prefixes()) {
super.remove(trans, peer, id);
}
}
final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.update.PathAttributes attributes) {
final CLinkstateDestination key =
((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.
- update.path.attributes.mp.reach.nlri.advertized.routes.nlri.Linkstate) nlri.getAdvertizedRoutes().getNlri()).getCLinkstateDestination();
+ update.path.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstate) nlri.getAdvertizedRoutes().getDestinationType()).getCLinkstateDestination();
RIBEntryData data = null;
switch (key.getNlriType()) {
final MpUnreachNlri nlri) {
final CLinkstateDestination key =
((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.
- update.path.attributes.mp.unreach.nlri.withdrawn.routes.nlri.Linkstate) nlri.getWithdrawnRoutes().getNlri()).getCLinkstateDestination();
+ update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstate) nlri.getWithdrawnRoutes().getDestinationType()).getCLinkstateDestination();
super.remove(trans, peer, key);
}
}
}
- public SERIALIZER getSerializer(final CLASS obj) {
- final Class<?> c = obj.getClass();
-
- for (Map.Entry<Class<? extends CLASS>, SERIALIZER> e : serializers.entrySet()) {
- if (e.getKey().isAssignableFrom(c)) {
- return e.getValue();
- }
- }
-
- return null;
+ public SERIALIZER getSerializer(final Class<? extends CLASS> clazz) {
+ return serializers.get(clazz);
}
}
public final class BgpLinkstateBundleTest extends AbstractBundleTest {
@Override
protected Collection<String> prerequisiteBundles() {
- return Lists.newArrayList("bgp-concepts", "bgp-parser-api", "concepts", "framework", "util");
+ return Lists.newArrayList("bgp-concepts", "bgp-parser-api", "bgp-parser-spi", "concepts", "framework", "util");
}
@Override
public final class BgpParserImplBundleTest extends AbstractBundleTest {
@Override
protected Collection<String> prerequisiteBundles() {
- return Lists.newArrayList("bgp-concepts", "bgp-linkstate", "bgp-parser-api", "bgp-util", "concepts", "framework", "util");
+ return Lists.newArrayList("bgp-concepts", "bgp-linkstate", "bgp-parser-api", "bgp-parser-spi", "bgp-util", "concepts", "framework", "util");
}
@Override
@Override
protected Collection<String> prerequisiteBundles() {
return Lists.newArrayList("concepts", "bgp-concepts", "bgp-linkstate", "bgp-parser-api",
- "bgp-parser-impl", "bgp-rib-api", "bgp-rib-spi", "bgp-util", "framework", "util");
+ "bgp-parser-impl", "bgp-parser-spi", "bgp-rib-api", "bgp-rib-spi",
+ "bgp-util", "framework", "util");
}
@Override
@Override
protected Collection<String> prerequisiteBundles() {
return Lists.newArrayList("concepts", "bgp-concepts", "bgp-linkstate", "bgp-parser-api",
- "bgp-parser-impl", "bgp-rib-api", "bgp-rib-impl", "bgp-rib-spi", "bgp-util", "framework", "util");
+ "bgp-parser-impl", "bgp-parser-spi", "bgp-rib-api", "bgp-rib-impl",
+ "bgp-rib-spi", "bgp-util", "framework", "util");
}
@Override
@Override
protected Collection<String> prerequisiteBundles() {
return Lists.newArrayList("bgp-parser-api", "bgp-concepts", "bgp-linkstate",
- "bgp-parser-impl", "bgp-util", "concepts", "framework", "bgp-rib-api",
- "bgp-rib-impl", "bgp-rib-spi", "util");
+ "bgp-parser-impl", "bgp-parser-spi", "bgp-util", "concepts",
+ "framework", "bgp-rib-api", "bgp-rib-impl", "bgp-rib-spi",
+ "util");
}
@Override
* 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;
+package org.opendaylight.protocol.util;
import java.util.ArrayList;
import java.util.Arrays;