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
8 package org.opendaylight.protocol.pcep.segment.routing;
10 import static com.google.common.base.Preconditions.checkArgument;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.Unpooled;
14 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
15 import org.opendaylight.protocol.util.BitArray;
16 import org.opendaylight.protocol.util.Ipv4Util;
17 import org.opendaylight.protocol.util.Ipv6Util;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.SidType;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.SrSubobject;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.Nai;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpAdjacency;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpAdjacencyBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpNodeId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpNodeIdBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.UnnumberedAdjacency;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.UnnumberedAdjacencyBuilder;
28 import org.opendaylight.yangtools.yang.common.Uint32;
29 import org.opendaylight.yangtools.yang.common.netty.ByteBufUtils;
31 public abstract class AbstractSrSubobjectParser {
32 protected static final int MINIMAL_LENGTH = 4;
33 protected static final int BITSET_LENGTH = 8;
34 protected static final int M_FLAG_POSITION = 7;
35 protected static final int C_FLAG_POSITION = 6;
36 protected static final int S_FLAG_POSITION = 5;
37 protected static final int F_FLAG_POSITION = 4;
38 protected static final int MPLS_LABEL_OFFSET = 12;
40 private static final int SID_TYPE_BITS_OFFSET = 4;
42 private static class SrSubobjectImpl implements SrSubobject {
43 private final boolean mflag;
44 private final boolean cflag;
45 private final SidType sidType;
46 private final Uint32 sid;
47 private final Nai nai;
49 SrSubobjectImpl(final boolean mflag, final boolean cflag, final SidType sidType, final Uint32 sid,
53 this.sidType = sidType;
59 public Class<SrSubobject> implementedInterface() {
60 return SrSubobject.class;
64 public Boolean isMFlag() {
69 public Boolean isCFlag() {
74 public SidType getSidType() {
79 public Uint32 getSid() {
89 public ByteBuf serializeSubobject(final SrSubobject srSubobject) {
90 final ByteBuf buffer = Unpooled.buffer(MINIMAL_LENGTH);
92 buffer.writeByte(srSubobject.getSidType().getIntValue() << SID_TYPE_BITS_OFFSET);
94 final BitArray bits = new BitArray(BITSET_LENGTH);
95 bits.set(M_FLAG_POSITION, srSubobject.isMFlag());
96 bits.set(C_FLAG_POSITION, srSubobject.isCFlag());
97 if (srSubobject.getSid() == null) {
98 bits.set(S_FLAG_POSITION, Boolean.TRUE);
100 if (srSubobject.getNai() == null) {
101 bits.set(F_FLAG_POSITION, Boolean.TRUE);
104 bits.toByteBuf(buffer);
106 checkArgument(srSubobject.getNai() != null || srSubobject.getSid() != null,
107 "Both SID and NAI are absent in SR subobject.");
108 if (srSubobject.getSid() != null) {
109 if (srSubobject.isMFlag()) {
110 buffer.writeInt(srSubobject.getSid().intValue() << MPLS_LABEL_OFFSET);
112 ByteBufUtils.writeOrZero(buffer, srSubobject.getSid());
116 final Nai nai = srSubobject.getNai();
118 serializeNai(nai, srSubobject.getSidType() ,buffer);
123 private static void serializeNai(final Nai nai, final SidType sidType, final ByteBuf buffer) {
126 Ipv4Util.writeIpv4Address(((IpNodeId) nai).getIpAddress().getIpv4AddressNoZone(), buffer);
129 Ipv6Util.writeIpv6Address(((IpNodeId) nai).getIpAddress().getIpv6AddressNoZone(), buffer);
132 Ipv4Util.writeIpv4Address(((IpAdjacency) nai).getLocalIpAddress().getIpv4AddressNoZone(), buffer);
133 Ipv4Util.writeIpv4Address(((IpAdjacency) nai).getRemoteIpAddress().getIpv4AddressNoZone(), buffer);
136 Ipv6Util.writeIpv6Address(((IpAdjacency) nai).getLocalIpAddress().getIpv6AddressNoZone(), buffer);
137 Ipv6Util.writeIpv6Address(((IpAdjacency) nai).getRemoteIpAddress().getIpv6AddressNoZone(), buffer);
140 final UnnumberedAdjacency unnumbered = (UnnumberedAdjacency) nai;
141 ByteBufUtils.writeOrZero(buffer, unnumbered.getLocalNodeId());
142 ByteBufUtils.writeOrZero(buffer, unnumbered.getLocalInterfaceId());
143 ByteBufUtils.writeOrZero(buffer, unnumbered.getRemoteNodeId());
144 ByteBufUtils.writeOrZero(buffer, unnumbered.getRemoteInterfaceId());
151 private static Nai parseNai(final SidType sidType, final ByteBuf buffer) {
154 return new IpNodeIdBuilder().setIpAddress(
155 new IpAddressNoZone(Ipv4Util.noZoneAddressForByteBuf(buffer))).build();
157 return new IpNodeIdBuilder().setIpAddress(
158 new IpAddressNoZone(Ipv6Util.noZoneAddressForByteBuf(buffer))).build();
160 return new IpAdjacencyBuilder()
161 .setLocalIpAddress(new IpAddressNoZone(Ipv4Util.noZoneAddressForByteBuf(buffer)))
162 .setRemoteIpAddress(new IpAddressNoZone(Ipv4Util.noZoneAddressForByteBuf(buffer))).build();
164 return new IpAdjacencyBuilder()
165 .setLocalIpAddress(new IpAddressNoZone(Ipv6Util.noZoneAddressForByteBuf(buffer)))
166 .setRemoteIpAddress(new IpAddressNoZone(Ipv6Util.noZoneAddressForByteBuf(buffer))).build();
168 return new UnnumberedAdjacencyBuilder()
169 .setLocalNodeId(ByteBufUtils.readUint32(buffer))
170 .setLocalInterfaceId(ByteBufUtils.readUint32(buffer))
171 .setRemoteNodeId(ByteBufUtils.readUint32(buffer))
172 .setRemoteInterfaceId(ByteBufUtils.readUint32(buffer)).build();
178 protected static SrSubobject parseSrSubobject(final ByteBuf buffer) throws PCEPDeserializerException {
179 final int sidTypeByte = buffer.readByte() >> SID_TYPE_BITS_OFFSET;
180 final SidType sidType = SidType.forValue(sidTypeByte);
181 final BitArray bitSet = BitArray.valueOf(buffer.readByte());
182 final boolean f = bitSet.get(F_FLAG_POSITION);
183 final boolean s = bitSet.get(S_FLAG_POSITION);
184 final boolean c = bitSet.get(C_FLAG_POSITION);
185 final boolean m = bitSet.get(M_FLAG_POSITION);
188 throw new PCEPDeserializerException("Both SID and NAI are absent in SR subobject.");
193 final long tmp = buffer.readUnsignedInt();
194 sid = Uint32.valueOf(m ? tmp >> MPLS_LABEL_OFFSET : tmp);
199 if (sidType != null && !f) {
200 nai = parseNai(sidType, buffer);
204 return new SrSubobjectImpl(m, c, sidType, sid, nai);