2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.protocol.pcep.segment.routing;
11 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv4Address;
12 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv6Address;
13 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedByte;
14 import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedInt;
16 import com.google.common.base.Preconditions;
17 import io.netty.buffer.ByteBuf;
18 import io.netty.buffer.Unpooled;
19 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
20 import org.opendaylight.protocol.util.BitArray;
21 import org.opendaylight.protocol.util.ByteBufWriteUtil;
22 import org.opendaylight.protocol.util.Ipv4Util;
23 import org.opendaylight.protocol.util.Ipv6Util;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.SidType;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.SrSubobject;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.Nai;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpAdjacency;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpAdjacencyBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpNodeId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpNodeIdBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.UnnumberedAdjacency;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.UnnumberedAdjacencyBuilder;
34 import org.opendaylight.yangtools.yang.binding.DataContainer;
36 public abstract class AbstractSrSubobjectParser {
38 protected static final int MINIMAL_LENGTH = 4;
39 protected static final int BITSET_LENGTH = 8;
40 protected static final int M_FLAG_POSITION = 7;
41 protected static final int C_FLAG_POSITION = 6;
42 protected static final int S_FLAG_POSITION = 5;
43 protected static final int F_FLAG_POSITION = 4;
44 protected static final int MPLS_LABEL_OFFSET = 12;
46 private static final int SID_TYPE_BITS_OFFSET = 4;
48 private static class SrSubobjectImpl implements SrSubobject {
50 private final boolean m;
51 private final boolean c;
52 private final SidType sidType;
53 private final Long sid;
54 private final Nai nai;
56 public SrSubobjectImpl(final boolean m, final boolean c, final SidType sidType,
57 final Long sid, final Nai nai) {
60 this.sidType = sidType;
66 public Class<? extends DataContainer> getImplementedInterface() {
67 return SrSubobject.class;
71 public Boolean isMFlag() {
76 public Boolean isCFlag() {
81 public SidType getSidType() {
86 public Long getSid() {
96 public ByteBuf serializeSubobject(final SrSubobject srSubobject) {
97 final ByteBuf buffer = Unpooled.buffer(MINIMAL_LENGTH);
99 writeUnsignedByte((short)(srSubobject.getSidType().getIntValue() << SID_TYPE_BITS_OFFSET), buffer);
101 final BitArray bits = new BitArray(BITSET_LENGTH);
102 bits.set(M_FLAG_POSITION, srSubobject.isMFlag());
103 bits.set(C_FLAG_POSITION, srSubobject.isCFlag());
104 if (srSubobject.getSid() == null) {
105 bits.set(S_FLAG_POSITION, Boolean.TRUE);
107 if (srSubobject.getNai() == null) {
108 bits.set(F_FLAG_POSITION, Boolean.TRUE);
111 bits.toByteBuf(buffer);
113 Preconditions.checkArgument(srSubobject.getNai() != null || srSubobject.getSid() != null, "Both SID and NAI are absent in SR subobject.");
114 if (srSubobject.getSid() != null) {
115 if (srSubobject.isMFlag()) {
116 writeUnsignedInt(srSubobject.getSid() << MPLS_LABEL_OFFSET, buffer);
118 writeUnsignedInt(srSubobject.getSid(), buffer);
122 final Nai nai = srSubobject.getNai();
124 serializeNai(nai, srSubobject.getSidType() ,buffer);
129 private static void serializeNai(final Nai nai, final SidType sidType, final ByteBuf buffer) {
132 writeIpv4Address(((IpNodeId) nai).getIpAddress().getIpv4AddressNoZone(), buffer);
135 writeIpv6Address(((IpNodeId) nai).getIpAddress().getIpv6AddressNoZone(), buffer);
138 writeIpv4Address(((IpAdjacency) nai).getLocalIpAddress().getIpv4AddressNoZone(), buffer);
139 writeIpv4Address(((IpAdjacency) nai).getRemoteIpAddress().getIpv4AddressNoZone(), buffer);
142 writeIpv6Address(((IpAdjacency) nai).getLocalIpAddress().getIpv6AddressNoZone(), buffer);
143 writeIpv6Address(((IpAdjacency) nai).getRemoteIpAddress().getIpv6AddressNoZone(), buffer);
146 final UnnumberedAdjacency unnumbered = (UnnumberedAdjacency) nai;
147 ByteBufWriteUtil.writeUnsignedInt(unnumbered.getLocalNodeId(), buffer);
148 ByteBufWriteUtil.writeUnsignedInt(unnumbered.getLocalInterfaceId(), buffer);
149 ByteBufWriteUtil.writeUnsignedInt(unnumbered.getRemoteNodeId(), buffer);
150 ByteBufWriteUtil.writeUnsignedInt(unnumbered.getRemoteInterfaceId(), buffer);
157 private static Nai parseNai(final SidType sidType, final ByteBuf buffer) {
160 return new IpNodeIdBuilder().setIpAddress(
161 new IpAddressNoZone(Ipv4Util.noZoneAddressForByteBuf(buffer))).build();
163 return new IpNodeIdBuilder().setIpAddress(
164 new IpAddressNoZone(Ipv6Util.noZoneAddressForByteBuf(buffer))).build();
166 return new IpAdjacencyBuilder()
167 .setLocalIpAddress(new IpAddressNoZone(Ipv4Util.noZoneAddressForByteBuf(buffer)))
168 .setRemoteIpAddress(new IpAddressNoZone(Ipv4Util.noZoneAddressForByteBuf(buffer))).build();
170 return new IpAdjacencyBuilder()
171 .setLocalIpAddress(new IpAddressNoZone(Ipv6Util.noZoneAddressForByteBuf(buffer)))
172 .setRemoteIpAddress(new IpAddressNoZone(Ipv6Util.noZoneAddressForByteBuf(buffer))).build();
174 return new UnnumberedAdjacencyBuilder().setLocalNodeId(buffer.readUnsignedInt())
175 .setLocalInterfaceId(buffer.readUnsignedInt()).setRemoteNodeId(buffer.readUnsignedInt())
176 .setRemoteInterfaceId(buffer.readUnsignedInt()).build();
182 protected static SrSubobject parseSrSubobject(final ByteBuf buffer) throws PCEPDeserializerException {
183 final int sidTypeByte = buffer.readByte() >> SID_TYPE_BITS_OFFSET;
184 final SidType sidType = SidType.forValue(sidTypeByte);
185 final BitArray bitSet = BitArray.valueOf(buffer.readByte());
186 final boolean f = bitSet.get(F_FLAG_POSITION);
187 final boolean s = bitSet.get(S_FLAG_POSITION);
188 final boolean c = bitSet.get(C_FLAG_POSITION);
189 final boolean m = bitSet.get(M_FLAG_POSITION);
192 throw new PCEPDeserializerException("Both SID and NAI are absent in SR subobject.");
197 tmp = buffer.readUnsignedInt() >>> MPLS_LABEL_OFFSET;
199 tmp = buffer.readUnsignedInt();
202 final Long sid = tmp;
204 if (sidType != null && !f) {
205 nai = parseNai(sidType, buffer);
209 return new SrSubobjectImpl(m, c, sidType, sid, nai);