2d75512eb68ab27ed123832b06dae95d11289606
[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 org.opendaylight.protocol.bgp.linkstate.attribute.sr.SidLabelIndexParser.Size;
13 import org.opendaylight.protocol.util.BitArray;
14 import org.opendaylight.protocol.util.ByteArray;
15 import org.opendaylight.protocol.util.Ipv4Util;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrLanAdjId;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrLanAdjIdBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.AdjSidTlv;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.Weight;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.Flags;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.IsisAdjFlagsCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.adj.flags.flags.OspfAdjFlagsCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev151014.sid.label.index.SidLabelIndex;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
28 import org.opendaylight.yangtools.yang.binding.DataContainer;
29
30 public final class SrLinkAttributesParser {
31
32     private static final int ISO_SYSTEM_ID_SIZE = 6;
33     private static final int RESERVED = 2;
34
35     /* Adj-SID flags */
36     private static final int ADDRESS_FAMILY_FLAG = 0;
37     private static final int BACKUP_ISIS = 1;
38     private static final int BACKUP_OSPF = 0;
39     private static final int VALUE_ISIS = 2;
40     private static final int VALUE_OSPF = 1;
41     private static final int VALUE_EPE = 0;
42     private static final int LOCAL_ISIS = 3;
43     private static final int LOCAL_OSPF = 2;
44     private static final int LOCAL_EPE = 1;
45     private static final int SET_ISIS = 4;
46     private static final int SET_OSPF = 3;
47     private static final int FLAGS_SIZE = 8;
48
49     /** OSPF flags
50        0 1 2 3 4 5 6 7
51       +-+-+-+-+-+-+-+-+
52       |B|V|L|S|       |
53       +-+-+-+-+-+-+-+-+
54
55        ISIS flags
56        0 1 2 3 4 5 6 7
57       +-+-+-+-+-+-+-+-+
58       |F|B|V|L|S|     |
59       +-+-+-+-+-+-+-+-+
60      */
61
62     private SrLinkAttributesParser() {
63         throw new UnsupportedOperationException();
64     }
65
66     public static AdjSidTlv parseAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) {
67         final Flags adjFlags;
68         final Weight weight;
69         final SidLabelIndex sidValue;
70         if (buffer.isReadable()) {
71             final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE);
72             adjFlags = parseFlags(flags, protocolId);
73             weight = new Weight(buffer.readUnsignedByte());
74             buffer.skipBytes(RESERVED);
75             sidValue = SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer);
76         } else {
77             adjFlags = null;
78             weight = null;
79             sidValue = null;
80         }
81         return new AdjSidTlv() {
82             @Override
83             public Class<? extends DataContainer> getImplementedInterface() {
84                 return AdjSidTlv.class;
85             }
86             @Override
87             public Weight getWeight() {
88                 return weight;
89             }
90             @Override
91             public SidLabelIndex getSidLabelIndex() {
92                 return sidValue;
93             }
94             @Override
95             public Flags getFlags() {
96                 return adjFlags;
97             }
98         };
99     }
100
101     public static SrLanAdjId parseLanAdjacencySegmentIdentifier(final ByteBuf buffer, final ProtocolId protocolId) {
102         if (!buffer.isReadable()) {
103             return new SrLanAdjIdBuilder().build();
104         }
105         final SrLanAdjIdBuilder srLanAdjIdBuilder = new SrLanAdjIdBuilder();
106         final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE);
107         srLanAdjIdBuilder.setFlags(parseFlags(flags, protocolId));
108         srLanAdjIdBuilder.setWeight(new Weight(buffer.readUnsignedByte()));
109         buffer.skipBytes(RESERVED);
110         if (protocolId.equals(ProtocolId.IsisLevel1) || protocolId.equals(ProtocolId.IsisLevel2)) {
111             srLanAdjIdBuilder.setIsoSystemId(new IsoSystemIdentifier(ByteArray.readBytes(buffer, ISO_SYSTEM_ID_SIZE)));
112         } else if (protocolId.equals(ProtocolId.Ospf)) {
113             srLanAdjIdBuilder.setNeighborId(Ipv4Util.addressForByteBuf(buffer));
114         }
115         // length determines a type of next field, which is used for parsing
116         srLanAdjIdBuilder.setSidLabelIndex(SidLabelIndexParser.parseSidLabelIndex(Size.forValue(buffer.readableBytes()), buffer));
117         return srLanAdjIdBuilder.build();
118     }
119
120     private static Flags parseFlags(final BitArray flags, final ProtocolId protocol) {
121         if (protocol == null) {
122             return null;
123         }
124         if (protocol.equals(ProtocolId.IsisLevel1) || protocol.equals(ProtocolId.IsisLevel2)) {
125             return new IsisAdjFlagsCaseBuilder()
126                 .setAddressFamily(flags.get(ADDRESS_FAMILY_FLAG))
127                 .setBackup(flags.get(BACKUP_ISIS))
128                 .setSet(flags.get(SET_ISIS)).build();
129         } else if (protocol.equals(ProtocolId.Ospf)) {
130             return new OspfAdjFlagsCaseBuilder()
131                 .setBackup(flags.get(BACKUP_OSPF))
132                 .setSet(flags.get(SET_OSPF)).build();
133         }
134         return null;
135     }
136
137     public static ByteBuf serializeAdjacencySegmentIdentifier(final AdjSidTlv adjSid) {
138         final ByteBuf value = Unpooled.buffer();
139         final BitArray flags = serializeAdjFlags(adjSid.getFlags(), adjSid.getSidLabelIndex());
140         flags.toByteBuf(value);
141         value.writeByte(adjSid.getWeight().getValue());
142         value.writeZero(RESERVED);
143         value.writeBytes(SidLabelIndexParser.serializeSidValue(adjSid.getSidLabelIndex()));
144         return value;
145     }
146
147     public static ByteBuf serializeLanAdjacencySegmentIdentifier(final SrLanAdjId srLanAdjId) {
148         final ByteBuf value = Unpooled.buffer();
149         final BitArray flags = serializeAdjFlags(srLanAdjId.getFlags(), srLanAdjId.getSidLabelIndex());
150         flags.toByteBuf(value);
151         value.writeByte(srLanAdjId.getWeight().getValue());
152         value.writeZero(RESERVED);
153         if (srLanAdjId.getIsoSystemId() != null) {
154             value.writeBytes(srLanAdjId.getIsoSystemId().getValue());
155         } else if (srLanAdjId.getNeighborId() != null) {
156             value.writeBytes(Ipv4Util.byteBufForAddress(srLanAdjId.getNeighborId()));
157         }
158         value.writeBytes(SidLabelIndexParser.serializeSidValue(srLanAdjId.getSidLabelIndex()));
159         return value;
160     }
161
162     private static BitArray serializeAdjFlags(final Flags flags, final SidLabelIndex sidLabelIndex) {
163         final BitArray bitFlags = new BitArray(FLAGS_SIZE);
164         if (flags instanceof OspfAdjFlagsCase) {
165             final OspfAdjFlagsCase ospfFlags = (OspfAdjFlagsCase) flags;
166             bitFlags.set(BACKUP_OSPF, ospfFlags.isBackup());
167             bitFlags.set(SET_OSPF, ospfFlags.isSet());
168             SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_OSPF, LOCAL_OSPF);
169         } else if (flags instanceof IsisAdjFlagsCase) {
170             final IsisAdjFlagsCase isisFlags = (IsisAdjFlagsCase) flags;
171             bitFlags.set(ADDRESS_FAMILY_FLAG, isisFlags.isAddressFamily());
172             bitFlags.set(BACKUP_ISIS, isisFlags.isBackup());
173             bitFlags.set(SET_ISIS, isisFlags.isSet());
174             SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_ISIS, LOCAL_ISIS);
175         } else if (flags == null){
176             SidLabelIndexParser.setFlags(sidLabelIndex, bitFlags, VALUE_EPE, LOCAL_EPE);
177         }
178         return bitFlags;
179     }
180
181 }