Enforce checkstyle in bgp-linkstate
[bgpcep.git] / bgp / extensions / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / impl / attribute / sr / SrLinkAttributesParser.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.bgp.linkstate.impl.attribute.sr;
9
10 import static org.opendaylight.protocol.bgp.linkstate.impl.attribute.LinkAttributesParser.SR_LAN_ADJ_ID;
11
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.rev180329.ProtocolId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.SrAdjIds;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.SrAdjIdsBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.attribute.SrLanAdjIds;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.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;
35
36 public final class SrLinkAttributesParser {
37
38     private static final int ISO_SYSTEM_ID_SIZE = 6;
39     private static final int RESERVED = 2;
40
41     /* Adj-SID flags */
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;
55
56     /*
57        OSPF flags
58        0 1 2 3 4 5 6 7
59       +-+-+-+-+-+-+-+-+
60       |B|V|L|S|       |
61       +-+-+-+-+-+-+-+-+
62
63        ISIS flags
64        0 1 2 3 4 5 6 7
65       +-+-+-+-+-+-+-+-+
66       |F|B|V|L|S|     |
67       +-+-+-+-+-+-+-+-+
68      */
69
70     private SrLinkAttributesParser() {
71
72     }
73
74     public static SrAdjIds parseAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) {
75         final Flags adjFlags;
76         final Weight weight;
77         final SidLabelIndex sidValue;
78         if (buffer.isReadable()) {
79             final BitArray flags = BitArray.valueOf(buffer, FLAGS_BITS_SIZE);
80             adjFlags = parseFlags(flags, protocolId);
81             weight = new Weight(buffer.readUnsignedByte());
82             buffer.skipBytes(RESERVED);
83             sidValue = SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer);
84         } else {
85             adjFlags = null;
86             weight = null;
87             sidValue = null;
88         }
89         return new SrAdjIdsBuilder().setFlags(adjFlags).setSidLabelIndex(sidValue).setWeight(weight).build();
90     }
91
92     public static EpeAdjSidTlv parseEpeAdjacencySegmentIdentifier(final ByteBuf buffer) {
93         final Weight weight;
94         final SidLabelIndex sidValue;
95         if (buffer.isReadable()) {
96             buffer.skipBytes(FLAGS_BYTE_SIZE);
97             weight = new Weight(buffer.readUnsignedByte());
98             buffer.skipBytes(RESERVED);
99             sidValue = SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer);
100         } else {
101             weight = null;
102             sidValue = null;
103         }
104         return new EpeAdjSidTlv() {
105             @Override
106             public Class<? extends DataContainer> getImplementedInterface() {
107                 return EpeAdjSidTlv.class;
108             }
109
110             @Override
111             public Weight getWeight() {
112                 return weight;
113             }
114
115             @Override
116             public SidLabelIndex getSidLabelIndex() {
117                 return sidValue;
118             }
119         };
120     }
121
122     public static SrLanAdjIds parseLanAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) {
123         if (!buffer.isReadable()) {
124             return new SrLanAdjIdsBuilder().build();
125         }
126         final SrLanAdjIdsBuilder srLanAdjIdBuilder = new SrLanAdjIdsBuilder();
127         final BitArray flags = BitArray.valueOf(buffer, FLAGS_BITS_SIZE);
128         srLanAdjIdBuilder.setFlags(parseFlags(flags, protocolId));
129         srLanAdjIdBuilder.setWeight(new Weight(buffer.readUnsignedByte()));
130         buffer.skipBytes(RESERVED);
131         switch (protocolId) {
132             case IsisLevel1:
133             case IsisLevel2:
134                 srLanAdjIdBuilder.setIsoSystemId(new IsoSystemIdentifier(
135                     ByteArray.readBytes(buffer, ISO_SYSTEM_ID_SIZE)));
136                 break;
137             case Ospf:
138             case OspfV3:
139                 srLanAdjIdBuilder.setNeighborId(Ipv4Util.addressForByteBuf(buffer));
140                 break;
141             default:
142                 return null;
143         }
144         // length determines a type of next field, which is used for parsing
145         srLanAdjIdBuilder.setSidLabelIndex(SidLabelIndexParser.parseSidLabelIndex(
146             Size.forValue(buffer.readableBytes()), buffer));
147         return srLanAdjIdBuilder.build();
148     }
149
150     private static Flags parseFlags(final BitArray flags, final ProtocolId protocol) {
151         if (protocol == null) {
152             return null;
153         }
154         switch (protocol) {
155             case IsisLevel1:
156             case IsisLevel2:
157                 return new IsisAdjFlagsCaseBuilder().setAddressFamily(flags.get(ADDRESS_FAMILY_FLAG))
158                         .setBackup(flags.get(BACKUP_ISIS))
159                         .setSet(flags.get(SET_ISIS)).build();
160             case Ospf:
161             case OspfV3:
162                 return new OspfAdjFlagsCaseBuilder().setBackup(flags.get(BACKUP_OSPF)).setSet(flags.get(SET_OSPF))
163                         .build();
164             default:
165                 return null;
166         }
167     }
168
169     public static <T extends EpeAdjSidTlv> void serializeAdjacencySegmentIdentifiers(final List<T> adjSids,
170             final int type, final ByteBuf byteAggregator) {
171         adjSids.forEach(id -> TlvUtil.writeTLV(type, serializeAdjacencySegmentIdentifier(id), byteAggregator));
172     }
173
174     public static <T extends EpeAdjSidTlv> ByteBuf serializeAdjacencySegmentIdentifier(final T adjSid) {
175         final ByteBuf value = Unpooled.buffer();
176         if (adjSid instanceof SrAdjIds) {
177             final BitArray flags = serializeAdjFlags(((SrAdjIds) adjSid).getFlags(), adjSid.getSidLabelIndex());
178             flags.toByteBuf(value);
179         } else {
180             value.writeZero(FLAGS_BYTE_SIZE);
181         }
182         value.writeByte(adjSid.getWeight().getValue());
183         value.writeZero(RESERVED);
184         value.writeBytes(SidLabelIndexParser.serializeSidValue(adjSid.getSidLabelIndex()));
185         return value;
186     }
187
188     public static void serializeLanAdjacencySegmentIdentifiers(final List<SrLanAdjIds> srLanAdjIds,
189             final ByteBuf byteAggregator) {
190         for (final SrLanAdjIds id : srLanAdjIds) {
191             TlvUtil.writeTLV(SR_LAN_ADJ_ID, serializeLanAdjacencySegmentIdentifier(id), byteAggregator);
192         }
193     }
194
195     public static ByteBuf serializeLanAdjacencySegmentIdentifier(final SrLanAdjIds srLanAdjId) {
196         final ByteBuf value = Unpooled.buffer();
197         final BitArray flags = serializeAdjFlags(srLanAdjId.getFlags(), srLanAdjId.getSidLabelIndex());
198         flags.toByteBuf(value);
199         value.writeByte(srLanAdjId.getWeight().getValue());
200         value.writeZero(RESERVED);
201         if (srLanAdjId.getIsoSystemId() != null) {
202             value.writeBytes(srLanAdjId.getIsoSystemId().getValue());
203         } else if (srLanAdjId.getNeighborId() != null) {
204             value.writeBytes(Ipv4Util.byteBufForAddress(srLanAdjId.getNeighborId()));
205         }
206         value.writeBytes(SidLabelIndexParser.serializeSidValue(srLanAdjId.getSidLabelIndex()));
207         return value;
208     }
209
210     private static BitArray serializeAdjFlags(final Flags flags, final SidLabelIndex sidLabelIndex) {
211         final BitArray bitFlags = new BitArray(FLAGS_BITS_SIZE);
212         if (flags instanceof OspfAdjFlagsCase) {
213             final OspfAdjFlagsCase ospfFlags = (OspfAdjFlagsCase) flags;
214             bitFlags.set(BACKUP_OSPF, ospfFlags.isBackup());
215             bitFlags.set(SET_OSPF, ospfFlags.isSet());
216             SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_OSPF, LOCAL_OSPF);
217         } else if (flags instanceof IsisAdjFlagsCase) {
218             final IsisAdjFlagsCase isisFlags = (IsisAdjFlagsCase) flags;
219             bitFlags.set(ADDRESS_FAMILY_FLAG, isisFlags.isAddressFamily());
220             bitFlags.set(BACKUP_ISIS, isisFlags.isBackup());
221             bitFlags.set(SET_ISIS, isisFlags.isSet());
222             SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_ISIS, LOCAL_ISIS);
223         } else if (flags == null) {
224             SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_EPE, LOCAL_EPE);
225         }
226         return bitFlags;
227     }
228 }