From: Claudio D. Gasparini Date: Sun, 30 Aug 2015 12:48:47 +0000 (+0200) Subject: BUG 2230: RSVP RRO Subobjects X-Git-Tag: release/beryllium~173 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=d0688ef44bcf935ea506486920838b0f28a38c6b;p=bgpcep.git BUG 2230: RSVP RRO Subobjects -Implementation of RRO subobjects parsers/serializers Change-Id: I06284a94601f0e022c59f323d6d38d47dcd4af3a Signed-off-by: Claudio D. Gasparini --- diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROIpv4PrefixSubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROIpv4PrefixSubobjectParser.java new file mode 100644 index 0000000000..5c5a87ec8f --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROIpv4PrefixSubobjectParser.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv4Prefix; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectSerializer; +import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException; +import org.opendaylight.protocol.util.BitArray; +import org.opendaylight.protocol.util.ByteArray; +import org.opendaylight.protocol.util.Ipv4Util; +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.rsvp.rev150820.IpPrefixSubobject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.IpPrefixCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.IpPrefixCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder; + +/** + * Parser for {@link IpPrefixCase} + */ +public class RROIpv4PrefixSubobjectParser implements RROSubobjectParser, RROSubobjectSerializer { + + public static final int TYPE = 1; + + private static final int PREFIX_F_LENGTH = 1; + private static final int FLAGS_SIZE = 8; + + private static final int PREFIX4_F_OFFSET = Ipv4Util.IP4_LENGTH; + + private static final int CONTENT4_LENGTH = Ipv4Util.IP4_LENGTH + PREFIX_F_LENGTH + FLAGS_SIZE / Byte.SIZE; + + private static final int LPA_F_OFFSET = 7; + private static final int LPIU_F_OFFSET = 6; + + @Override + public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { + Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + if (buffer.readableBytes() != CONTENT4_LENGTH) { + throw new RSVPParsingException("Wrong length of array of bytes. Passed: " + buffer.readableBytes() + ";"); + } + final SubobjectContainerBuilder builder = new SubobjectContainerBuilder(); + final int length = buffer.getUnsignedByte(PREFIX4_F_OFFSET); + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.ip.prefix._case.IpPrefix prefix = new IpPrefixBuilder().setIpPrefix( + new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.readBytes(buffer, Ipv4Util.IP4_LENGTH), length))).build(); + buffer.skipBytes(PREFIX_F_LENGTH); + final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); + builder.setProtectionAvailable(flags.get(LPA_F_OFFSET)); + builder.setProtectionInUse(flags.get(LPIU_F_OFFSET)); + builder.setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(prefix).build()); + return builder.build(); + } + + @Override + public void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + Preconditions.checkArgument(subobject.getSubobjectType() instanceof IpPrefixCase, "Unknown subobject instance. Passed %s. Needed IpPrefixCase.", subobject.getSubobjectType().getClass()); + final IpPrefixSubobject specObj = ((IpPrefixCase) subobject.getSubobjectType()).getIpPrefix(); + final IpPrefix prefix = specObj.getIpPrefix(); + Preconditions.checkArgument(prefix.getIpv4Prefix() != null || prefix.getIpv6Prefix() != null, "Unknown AbstractPrefix instance. Passed %s.", prefix.getClass()); + if (prefix.getIpv6Prefix() != null) { + new RROIpv6PrefixSubobjectParser().serializeSubobject(subobject, buffer); + } else { + final BitArray flags = new BitArray(FLAGS_SIZE); + flags.set(LPA_F_OFFSET, subobject.isProtectionAvailable()); + flags.set(LPIU_F_OFFSET, subobject.isProtectionInUse()); + final ByteBuf body = Unpooled.buffer(CONTENT4_LENGTH); + Preconditions.checkArgument(prefix.getIpv4Prefix() != null, "Ipv4Prefix is mandatory."); + writeIpv4Prefix(prefix.getIpv4Prefix(), body); + flags.toByteBuf(body); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } + } +} diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROIpv6PrefixSubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROIpv6PrefixSubobjectParser.java new file mode 100644 index 0000000000..c83b3b19d3 --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROIpv6PrefixSubobjectParser.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv6Prefix; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectSerializer; +import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException; +import org.opendaylight.protocol.util.BitArray; +import org.opendaylight.protocol.util.ByteArray; +import org.opendaylight.protocol.util.Ipv6Util; +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.rsvp.rev150820.IpPrefixSubobject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.IpPrefixCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.IpPrefixCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder; + +/** + * Parser for {@link IpPrefixCase} + */ +public class RROIpv6PrefixSubobjectParser implements RROSubobjectParser, RROSubobjectSerializer { + + public static final int TYPE = 2; + + private static final int PREFIX_F_LENGTH = 1; + private static final int FLAGS_SIZE = 8; + + private static final int PREFIX_F_OFFSET = Ipv6Util.IPV6_LENGTH; + + private static final int CONTENT_LENGTH = Ipv6Util.IPV6_LENGTH + PREFIX_F_LENGTH + FLAGS_SIZE / Byte.SIZE; + + private static final int LPA_F_OFFSET = 7; + private static final int LPIU_F_OFFSET = 6; + + @Override + public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { + Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + final SubobjectContainerBuilder builder = new SubobjectContainerBuilder(); + if (buffer.readableBytes() != CONTENT_LENGTH) { + throw new RSVPParsingException("Wrong length of array of bytes. Passed: " + buffer.readableBytes() + ";"); + } + final int length = buffer.getUnsignedByte(PREFIX_F_OFFSET); + final IpPrefixBuilder prefix = new IpPrefixBuilder().setIpPrefix(new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.readBytes(buffer, + Ipv6Util.IPV6_LENGTH), length))); + buffer.skipBytes(PREFIX_F_LENGTH); + final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); + builder.setProtectionAvailable(flags.get(LPA_F_OFFSET)); + builder.setProtectionInUse(flags.get(LPIU_F_OFFSET)); + builder.setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(prefix.build()).build()); + return builder.build(); + } + + @Override + public void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + Preconditions.checkArgument(subobject.getSubobjectType() instanceof IpPrefixCase, "Unknown subobject instance. Passed %s. Needed IpPrefixCase.", subobject.getSubobjectType().getClass()); + final IpPrefixSubobject specObj = ((IpPrefixCase) subobject.getSubobjectType()).getIpPrefix(); + final IpPrefix prefix = specObj.getIpPrefix(); + final BitArray flags = new BitArray(FLAGS_SIZE); + flags.set(LPA_F_OFFSET, subobject.isProtectionAvailable()); + flags.set(LPIU_F_OFFSET, subobject.isProtectionInUse()); + final ByteBuf body = Unpooled.buffer(CONTENT_LENGTH); + Preconditions.checkArgument(prefix.getIpv6Prefix() != null, "Ipv6Prefix is mandatory."); + writeIpv6Prefix(prefix.getIpv6Prefix(), body); + flags.toByteBuf(body); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } +} diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROLabelSubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROLabelSubobjectParser.java new file mode 100644 index 0000000000..3049920d24 --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROLabelSubobjectParser.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.spi.LabelRegistry; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectSerializer; +import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException; +import org.opendaylight.protocol.util.BitArray; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.label.subobject.LabelType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.LabelCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.LabelCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.label._case.Label; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.label._case.LabelBuilder; + +public class RROLabelSubobjectParser implements RROSubobjectParser, RROSubobjectSerializer { + + public static final int TYPE = 3; + + public static final int FLAGS_SIZE = 8; + + public static final int C_TYPE_F_LENGTH = 1; + + public static final int C_TYPE_F_OFFSET = FLAGS_SIZE / Byte.SIZE; + + public static final int HEADER_LENGTH = C_TYPE_F_OFFSET + C_TYPE_F_LENGTH; + + public static final int U_FLAG_OFFSET = 0; + public static final int G_FLAG_OFFSET = 7; + + private final LabelRegistry registry; + + public RROLabelSubobjectParser(final LabelRegistry labelReg) { + this.registry = Preconditions.checkNotNull(labelReg); + } + + @Override + public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { + Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + if (buffer.readableBytes() < HEADER_LENGTH) { + throw new RSVPParsingException("Wrong length of array of bytes. Passed: " + buffer.readableBytes() + "; Expected: >" + + HEADER_LENGTH + "."); + } + final BitArray reserved = BitArray.valueOf(buffer, FLAGS_SIZE); + + final short cType = buffer.readUnsignedByte(); + + final LabelType labelType = this.registry.parseLabel(cType, buffer.slice()); + if (labelType == null) { + throw new RSVPParsingException("Unknown C-TYPE for ero label subobject. Passed: " + cType); + } + final LabelBuilder builder = new LabelBuilder(); + builder.setUniDirectional(reserved.get(U_FLAG_OFFSET)); + builder.setGlobal(reserved.get(G_FLAG_OFFSET)); + builder.setLabelType(labelType); + return new SubobjectContainerBuilder().setSubobjectType(new LabelCaseBuilder().setLabel(builder.build()).build()).build(); + } + + @Override + public void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + Preconditions.checkNotNull(subobject.getSubobjectType(), "Subobject type cannot be empty."); + final Label label = ((LabelCase) subobject.getSubobjectType()).getLabel(); + final ByteBuf body = Unpooled.buffer(); + this.registry.serializeLabel(label.isUniDirectional(), label.isGlobal(), label.getLabelType(), body); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } +} diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROPathKey128SubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROPathKey128SubobjectParser.java new file mode 100644 index 0000000000..61a285e8d7 --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROPathKey128SubobjectParser.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedShort; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectParser; +import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException; +import org.opendaylight.protocol.util.ByteArray; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PathKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PceId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.PathKeyCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.PathKeyCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.path.key._case.PathKeyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainerBuilder; + +public class RROPathKey128SubobjectParser implements RROSubobjectParser { + + public static final int TYPE = 65; + + private static final int PK_F_LENGTH = 2; + + private static final int PCE128_ID_F_LENGTH = 16; + + private static final int PK_F_OFFSET = 0; + private static final int PCE_ID_F_OFFSET = PK_F_OFFSET + PK_F_LENGTH; + + private static final int CONTENT128_LENGTH = PCE_ID_F_OFFSET + PCE128_ID_F_LENGTH; + + @Override + public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { + Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + if (buffer.readableBytes() != CONTENT128_LENGTH) { + throw new RSVPParsingException("Wrong length of array of bytes. Passed: " + buffer.readableBytes() + "; Expected: >" + + CONTENT128_LENGTH + "."); + } + final int pathKey = buffer.readUnsignedShort(); + final byte[] pceId = ByteArray.readBytes(buffer, PCE128_ID_F_LENGTH); + final SubobjectContainerBuilder builder = new SubobjectContainerBuilder(); + final PathKeyBuilder pBuilder = new PathKeyBuilder(); + pBuilder.setPceId(new PceId(pceId)); + pBuilder.setPathKey(new PathKey(pathKey)); + builder.setSubobjectType(new PathKeyCaseBuilder().setPathKey(pBuilder.build()).build()); + return builder.build(); + } + + public static void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + final PathKeyCase pkcase = (PathKeyCase) subobject.getSubobjectType(); + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.path.key._case.PathKey pk = pkcase.getPathKey(); + final ByteBuf body = Unpooled.buffer(); + Preconditions.checkArgument(pk.getPathKey() != null, "PathKey is mandatory."); + writeUnsignedShort(pk.getPathKey().getValue(), body); + Preconditions.checkArgument(pk.getPceId() != null, "PceId is mandatory."); + body.writeBytes(pk.getPceId().getBinary()); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } +} diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROPathKey32SubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROPathKey32SubobjectParser.java new file mode 100644 index 0000000000..16e629354c --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROPathKey32SubobjectParser.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedShort; +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectSerializer; +import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException; +import org.opendaylight.protocol.util.ByteArray; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PathKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PceId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.PathKeyCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.PathKeyCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.path.key._case.PathKeyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainerBuilder; + +public class RROPathKey32SubobjectParser implements RROSubobjectParser, RROSubobjectSerializer { + + public static final int TYPE = 64; + + private static final int PK_F_LENGTH = 2; + private static final int PCE_ID_F_LENGTH = 4; + + private static final int PK_F_OFFSET = 0; + private static final int PCE_ID_F_OFFSET = PK_F_OFFSET + PK_F_LENGTH; + + private static final int CONTENT_LENGTH = PCE_ID_F_OFFSET + PCE_ID_F_LENGTH; + + @Override + public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { + Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + if (buffer.readableBytes() != CONTENT_LENGTH) { + throw new RSVPParsingException("Wrong length of array of bytes. Passed: " + buffer.readableBytes() + "; Expected: >" + + CONTENT_LENGTH + "."); + } + final int pathKey = buffer.readUnsignedShort(); + final byte[] pceId = ByteArray.readBytes(buffer, PCE_ID_F_LENGTH); + final SubobjectContainerBuilder builder = new SubobjectContainerBuilder(); + final PathKeyBuilder pBuilder = new PathKeyBuilder(); + pBuilder.setPceId(new PceId(pceId)); + pBuilder.setPathKey(new PathKey(pathKey)); + builder.setSubobjectType(new PathKeyCaseBuilder().setPathKey(pBuilder.build()).build()); + return builder.build(); + } + + @Override + public void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + Preconditions.checkArgument(subobject.getSubobjectType() instanceof PathKeyCase, "Unknown subobject instance. Passed %s. Needed PathKey.", subobject.getSubobjectType().getClass()); + final PathKeyCase pkcase = (PathKeyCase) subobject.getSubobjectType(); + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobject.subobject.type.path.key._case.PathKey pk = pkcase.getPathKey(); + final ByteBuf body = Unpooled.buffer(); + Preconditions.checkArgument(pk.getPceId() != null, "PceId is mandatory."); + if(pk.getPceId().getBinary().length == 16) { + RROPathKey128SubobjectParser.serializeSubobject(subobject,buffer); + } + Preconditions.checkArgument(pk.getPathKey() != null, "PathKey is mandatory."); + Preconditions.checkArgument(pk.getPceId().getBinary().length == 4, "PathKey 32Bit is mandatory."); + writeUnsignedShort(pk.getPathKey().getValue(), body); + body.writeBytes(pk.getPceId().getBinary()); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } +} diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROSubobjectUtil.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROSubobjectUtil.java new file mode 100644 index 0000000000..7aa154fe71 --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROSubobjectUtil.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import io.netty.buffer.ByteBuf; + +class RROSubobjectUtil { + private static final int HEADER_SIZE = 2; + + private RROSubobjectUtil() { + throw new UnsupportedOperationException(); + } + + public static void formatSubobject(final int type, final ByteBuf body, final ByteBuf buffer) { + buffer.writeByte(type); + buffer.writeByte(body.writerIndex() + HEADER_SIZE); + buffer.writeBytes(body); + } +} diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROUnnumberedInterfaceSubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROUnnumberedInterfaceSubobjectParser.java new file mode 100644 index 0000000000..63e64dabdb --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/RROUnnumberedInterfaceSubobjectParser.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedInt; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectSerializer; +import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException; +import org.opendaylight.protocol.util.BitArray; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.UnnumberedSubobject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.UnnumberedCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.UnnumberedCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.unnumbered._case.UnnumberedBuilder; + +/** + * Parser for {@link UnnumberedCase} + */ +public class RROUnnumberedInterfaceSubobjectParser implements RROSubobjectParser, RROSubobjectSerializer { + + public static final int TYPE = 4; + + private static final int FLAGS_SIZE = 8; + private static final int RESERVED = 1; + + private static final int CONTENT_LENGTH = 10; + + private static final int LPA_F_OFFSET = 7; + private static final int LPIU_F_OFFSET = 6; + + @Override + public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { + Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + if (buffer.readableBytes() != CONTENT_LENGTH) { + throw new RSVPParsingException("Wrong length of array of bytes. Passed: " + buffer.readableBytes() + "; Expected: " + + CONTENT_LENGTH + "."); + } + final SubobjectContainerBuilder builder = new SubobjectContainerBuilder(); + final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE); + builder.setProtectionAvailable(flags.get(LPA_F_OFFSET)); + builder.setProtectionInUse(flags.get(LPIU_F_OFFSET)); + final UnnumberedBuilder ubuilder = new UnnumberedBuilder(); + buffer.skipBytes(RESERVED); + ubuilder.setRouterId(buffer.readUnsignedInt()); + ubuilder.setInterfaceId(buffer.readUnsignedInt()); + builder.setSubobjectType(new UnnumberedCaseBuilder().setUnnumbered(ubuilder.build()).build()); + return builder.build(); + } + + @Override + public void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + Preconditions.checkArgument(subobject.getSubobjectType() instanceof UnnumberedCase, "Unknown subobject instance. Passed %s. Needed UnnumberedCase.", subobject.getSubobjectType().getClass()); + final UnnumberedSubobject specObj = ((UnnumberedCase) subobject.getSubobjectType()).getUnnumbered(); + final BitArray flags = new BitArray(FLAGS_SIZE); + flags.set(LPA_F_OFFSET, subobject.isProtectionAvailable()); + flags.set(LPIU_F_OFFSET, subobject.isProtectionInUse()); + final ByteBuf body = Unpooled.buffer(CONTENT_LENGTH); + flags.toByteBuf(body); + body.writeZero(RESERVED); + Preconditions.checkArgument(specObj.getRouterId() != null, "RouterId is mandatory."); + writeUnsignedInt(specObj.getRouterId(), body); + Preconditions.checkArgument(specObj.getInterfaceId() != null, "InterfaceId is mandatory."); + writeUnsignedInt(specObj.getInterfaceId(), body); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } +} \ No newline at end of file diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/SRROBasicProtectionSubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/SRROBasicProtectionSubobjectParser.java new file mode 100644 index 0000000000..2f27d3bb37 --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/SRROBasicProtectionSubobjectParser.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.impl.te.ProtectionCommonParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectSerializer; +import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.protection.subobject.ProtectionSubobject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.record.route.object.secondary.record.route.object.subobject.container.subobject.type.BasicProtectionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.record.route.object.secondary.record.route.object.subobject.container.subobject.type.BasicProtectionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.record.route.object.secondary.record.route.object.subobject.container.subobject.type.DynamicControlProtectionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.record.route.object.secondary.record.route.object.subobject.container.subobject.type.basic.protection._case.BasicProtectionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.record.route.object.secondary.record.route.object.subobject.container.subobject.type.dynamic.control.protection._case.DynamicControlProtectionBuilder; + +/** + * Parser for {@link BasicProtectionCase} + */ +public class SRROBasicProtectionSubobjectParser extends ProtectionCommonParser implements RROSubobjectParser, RROSubobjectSerializer { + + public static final int TYPE = 37; + public static final Short CTYPE = 1; + + @Override + public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException { + Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + final SubobjectContainerBuilder builder = new SubobjectContainerBuilder(); + //skip reserved + buffer.readByte(); + final short cType = buffer.readUnsignedByte(); + final ProtectionSubobject prot = parseCommonProtectionBody(cType, buffer); + if (cType == CTYPE) { + builder.setSubobjectType(new BasicProtectionCaseBuilder().setBasicProtection(new BasicProtectionBuilder() + .setProtectionSubobject(prot).build()).build()); + } else if (cType == SRRODynamicProtectionSubobjectParser.CTYPE) { + builder.setSubobjectType(new DynamicControlProtectionCaseBuilder().setDynamicControlProtection(new + DynamicControlProtectionBuilder().setProtectionSubobject(prot).build()).build()); + } + return builder.build(); + } + + + @Override + public void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + Preconditions.checkArgument(subobject.getSubobjectType() instanceof BasicProtectionCase, "Unknown subobject instance. Passed %s. Needed UnnumberedCase.", subobject.getSubobjectType().getClass()); + final ProtectionSubobject protObj = ((BasicProtectionCase) subobject.getSubobjectType()).getBasicProtection() + .getProtectionSubobject(); + final ByteBuf body = Unpooled.buffer(); + serializeBody(CTYPE, protObj, body); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } +} diff --git a/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/SRRODynamicProtectionSubobjectParser.java b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/SRRODynamicProtectionSubobjectParser.java new file mode 100644 index 0000000000..16fa67d051 --- /dev/null +++ b/rsvp/impl/src/main/java/org/opendaylight/protocol/rsvp/parser/impl/subobject/rro/SRRODynamicProtectionSubobjectParser.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015 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.rsvp.parser.impl.subobject.rro; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.rsvp.parser.impl.te.ProtectionCommonParser; +import org.opendaylight.protocol.rsvp.parser.spi.RROSubobjectSerializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.protection.subobject.ProtectionSubobject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.list.SubobjectContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.record.route.object.secondary.record.route.object.subobject.container.subobject.type.DynamicControlProtectionCase; + +public class SRRODynamicProtectionSubobjectParser extends ProtectionCommonParser implements RROSubobjectSerializer { + public static final int TYPE = 37; + public static final Short CTYPE = 2; + + @Override + public void serializeSubobject(final SubobjectContainer subobject, final ByteBuf buffer) { + Preconditions.checkArgument(subobject.getSubobjectType() instanceof DynamicControlProtectionCase, "Unknown " + + "subobject instance. Passed %s. Needed UnnumberedCase.", subobject.getSubobjectType()); + final ProtectionSubobject protObj = ((DynamicControlProtectionCase) subobject.getSubobjectType()) + .getDynamicControlProtection().getProtectionSubobject(); + final ByteBuf body = Unpooled.buffer(); + serializeBody(CTYPE, protObj, body); + RROSubobjectUtil.formatSubobject(TYPE, body, buffer); + } +}