2 * Copyright (c) 2014 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.bgp.linkstate.impl.attribute.sr;
10 import static org.opendaylight.protocol.bgp.linkstate.impl.attribute.LinkAttributesParser.SR_LAN_ADJ_ID;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.Unpooled;
14 import java.util.List;
15 import org.opendaylight.protocol.bgp.linkstate.impl.attribute.sr.SidLabelIndexParser.Size;
16 import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
17 import org.opendaylight.protocol.util.BitArray;
18 import org.opendaylight.protocol.util.ByteArray;
19 import org.opendaylight.protocol.util.Ipv4Util;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev171207.ProtocolId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev171207.linkstate.attribute.SrAdjIds;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev171207.linkstate.attribute.SrAdjIdsBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev171207.linkstate.attribute.SrLanAdjIds;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev171207.linkstate.attribute.SrLanAdjIdsBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.EpeAdjSidTlv;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.Weight;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.Flags;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCaseBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCaseBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.sid.label.index.SidLabelIndex;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
34 import org.opendaylight.yangtools.yang.binding.DataContainer;
36 public final class SrLinkAttributesParser {
38 private static final int ISO_SYSTEM_ID_SIZE = 6;
39 private static final int RESERVED = 2;
42 private static final int ADDRESS_FAMILY_FLAG = 0;
43 private static final int BACKUP_ISIS = 1;
44 private static final int BACKUP_OSPF = 0;
45 private static final int VALUE_ISIS = 2;
46 private static final int VALUE_OSPF = 1;
47 private static final int VALUE_EPE = 0;
48 private static final int LOCAL_ISIS = 3;
49 private static final int LOCAL_OSPF = 2;
50 private static final int LOCAL_EPE = 1;
51 private static final int SET_ISIS = 4;
52 private static final int SET_OSPF = 3;
53 private static final int FLAGS_BITS_SIZE = 8;
54 private static final int FLAGS_BYTE_SIZE = 1;
69 private SrLinkAttributesParser() {
70 throw new UnsupportedOperationException();
73 public static SrAdjIds parseAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) {
76 final SidLabelIndex sidValue;
77 if (buffer.isReadable()) {
78 final BitArray flags = BitArray.valueOf(buffer, FLAGS_BITS_SIZE);
79 adjFlags = parseFlags(flags, protocolId);
80 weight = new Weight(buffer.readUnsignedByte());
81 buffer.skipBytes(RESERVED);
82 sidValue = SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer);
88 return new SrAdjIdsBuilder().setFlags(adjFlags).setSidLabelIndex(sidValue).setWeight(weight).build();
91 public static EpeAdjSidTlv parseEpeAdjacencySegmentIdentifier(final ByteBuf buffer) {
93 final SidLabelIndex sidValue;
94 if (buffer.isReadable()) {
95 buffer.skipBytes(FLAGS_BYTE_SIZE);
96 weight = new Weight(buffer.readUnsignedByte());
97 buffer.skipBytes(RESERVED);
98 sidValue = SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer);
103 return new EpeAdjSidTlv() {
105 public Class<? extends DataContainer> getImplementedInterface() {
106 return EpeAdjSidTlv.class;
109 public Weight getWeight() {
113 public SidLabelIndex getSidLabelIndex() {
119 public static SrLanAdjIds parseLanAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) {
120 if (!buffer.isReadable()) {
121 return new SrLanAdjIdsBuilder().build();
123 final SrLanAdjIdsBuilder srLanAdjIdBuilder = new SrLanAdjIdsBuilder();
124 final BitArray flags = BitArray.valueOf(buffer, FLAGS_BITS_SIZE);
125 srLanAdjIdBuilder.setFlags(parseFlags(flags, protocolId));
126 srLanAdjIdBuilder.setWeight(new Weight(buffer.readUnsignedByte()));
127 buffer.skipBytes(RESERVED);
128 switch (protocolId) {
131 srLanAdjIdBuilder.setIsoSystemId(new IsoSystemIdentifier(ByteArray.readBytes(buffer, ISO_SYSTEM_ID_SIZE)));
135 srLanAdjIdBuilder.setNeighborId(Ipv4Util.addressForByteBuf(buffer));
140 // length determines a type of next field, which is used for parsing
141 srLanAdjIdBuilder.setSidLabelIndex(SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer));
142 return srLanAdjIdBuilder.build();
145 private static Flags parseFlags(final BitArray flags, final ProtocolId protocol) {
146 if (protocol == null) {
152 return new IsisAdjFlagsCaseBuilder().setAddressFamily(flags.get(ADDRESS_FAMILY_FLAG)).setBackup(flags.get(BACKUP_ISIS))
153 .setSet(flags.get(SET_ISIS)).build();
156 return new OspfAdjFlagsCaseBuilder().setBackup(flags.get(BACKUP_OSPF)).setSet(flags.get(SET_OSPF)).build();
162 public static <T extends EpeAdjSidTlv> void serializeAdjacencySegmentIdentifiers(final List<T> adjSids, final int type, final ByteBuf byteAggregator) {
163 adjSids.forEach(id -> TlvUtil.writeTLV(type, serializeAdjacencySegmentIdentifier(id), byteAggregator));
166 public static <T extends EpeAdjSidTlv> ByteBuf serializeAdjacencySegmentIdentifier(final T adjSid) {
167 final ByteBuf value = Unpooled.buffer();
168 if(adjSid instanceof SrAdjIds) {
169 final BitArray flags = serializeAdjFlags(((SrAdjIds) adjSid).getFlags(), adjSid.getSidLabelIndex());
170 flags.toByteBuf(value);
172 value.writeZero(FLAGS_BYTE_SIZE);
174 value.writeByte(adjSid.getWeight().getValue());
175 value.writeZero(RESERVED);
176 value.writeBytes(SidLabelIndexParser.serializeSidValue(adjSid.getSidLabelIndex()));
180 public static void serializeLanAdjacencySegmentIdentifiers(final List<SrLanAdjIds> srLanAdjIds, final ByteBuf byteAggregator) {
181 for (final SrLanAdjIds id : srLanAdjIds) {
182 TlvUtil.writeTLV(SR_LAN_ADJ_ID, serializeLanAdjacencySegmentIdentifier(id), byteAggregator);
186 public static ByteBuf serializeLanAdjacencySegmentIdentifier(final SrLanAdjIds srLanAdjId) {
187 final ByteBuf value = Unpooled.buffer();
188 final BitArray flags = serializeAdjFlags(srLanAdjId.getFlags(), srLanAdjId.getSidLabelIndex());
189 flags.toByteBuf(value);
190 value.writeByte(srLanAdjId.getWeight().getValue());
191 value.writeZero(RESERVED);
192 if (srLanAdjId.getIsoSystemId() != null) {
193 value.writeBytes(srLanAdjId.getIsoSystemId().getValue());
194 } else if (srLanAdjId.getNeighborId() != null) {
195 value.writeBytes(Ipv4Util.byteBufForAddress(srLanAdjId.getNeighborId()));
197 value.writeBytes(SidLabelIndexParser.serializeSidValue(srLanAdjId.getSidLabelIndex()));
201 private static BitArray serializeAdjFlags(final Flags flags, final SidLabelIndex sidLabelIndex) {
202 final BitArray bitFlags = new BitArray(FLAGS_BITS_SIZE);
203 if (flags instanceof OspfAdjFlagsCase) {
204 final OspfAdjFlagsCase ospfFlags = (OspfAdjFlagsCase) flags;
205 bitFlags.set(BACKUP_OSPF, ospfFlags.isBackup());
206 bitFlags.set(SET_OSPF, ospfFlags.isSet());
207 SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_OSPF, LOCAL_OSPF);
208 } else if (flags instanceof IsisAdjFlagsCase) {
209 final IsisAdjFlagsCase isisFlags = (IsisAdjFlagsCase) flags;
210 bitFlags.set(ADDRESS_FAMILY_FLAG, isisFlags.isAddressFamily());
211 bitFlags.set(BACKUP_ISIS, isisFlags.isBackup());
212 bitFlags.set(SET_ISIS, isisFlags.isSet());
213 SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_ISIS, LOCAL_ISIS);
214 } else if (flags == null){
215 SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_EPE, LOCAL_EPE);