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