Bug-2848: BGP-LS EPE extension: Peer Sid
[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.spi.TlvUtil;
13 import org.opendaylight.protocol.util.BitArray;
14 import org.opendaylight.protocol.util.ByteArray;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrLanAdjId;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.link.state.SrLanAdjIdBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.rev150206.AdjacencyFlags;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.rev150206.AdjacencySegmentIdentifier;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.rev150206.SidLabel;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.rev150206.Weight;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
22 import org.opendaylight.yangtools.yang.binding.DataContainer;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 public final class SrLinkAttributesParser {
27     private static final Logger LOG = LoggerFactory.getLogger(SrLinkAttributesParser.class);
28
29     private static final int ISO_SYSTEM_ID_SIZE = 6;
30
31     /* Adj-SID flags */
32     private static final int ADDRESS_FAMILY_FLAG = 0;
33     private static final int BACKUP_FLAG = 1;
34     private static final int VALUE_FLAG = 2;
35     private static final int LOCAL_FLAG = 3;
36     private static final int SET_FLAG = 4;
37     private static final int FLAGS_SIZE = 8;
38     private static final int SID_TYPE = 1;
39
40     private SrLinkAttributesParser() {
41         throw new UnsupportedOperationException();
42     }
43
44     public static AdjacencySegmentIdentifier parseAdjacencySegmentIdentifier(final ByteBuf buffer) {
45         final AdjacencyFlags adjFlags;
46         final Weight weight;
47         final SidLabel sidValue;
48         if (buffer.isReadable()) {
49             final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE);
50             adjFlags = new AdjacencyFlags(flags.get(ADDRESS_FAMILY_FLAG), flags.get(BACKUP_FLAG), flags.get(LOCAL_FLAG), flags.get(SET_FLAG), flags.get(VALUE_FLAG));
51             weight = new Weight(buffer.readUnsignedByte());
52             sidValue = parseSidSubTlv(buffer);
53         } else {
54             adjFlags = null;
55             weight = null;
56             sidValue = null;
57         }
58         return new AdjacencySegmentIdentifier() {
59
60             @Override
61             public Class<? extends DataContainer> getImplementedInterface() {
62                 return AdjacencySegmentIdentifier.class;
63             }
64
65             @Override
66             public Weight getWeight() {
67                 return weight;
68             }
69
70             @Override
71             public SidLabel getSid() {
72                 return sidValue;
73             }
74
75             @Override
76             public AdjacencyFlags getFlags() {
77                 return adjFlags;
78             }
79         };
80     }
81
82     public static ByteBuf serializeAdjacencySegmentIdentifier(final AdjacencySegmentIdentifier srAdjId) {
83         final ByteBuf value = Unpooled.buffer();
84         final AdjacencyFlags srAdjIdFlags = srAdjId.getFlags();
85         final BitArray flags = new BitArray(FLAGS_SIZE);
86         flags.set(ADDRESS_FAMILY_FLAG, srAdjIdFlags.isAddressFamily());
87         flags.set(BACKUP_FLAG, srAdjIdFlags.isBackup());
88         flags.set(VALUE_FLAG, srAdjIdFlags.isValue());
89         flags.set(LOCAL_FLAG, srAdjIdFlags.isLocal());
90         flags.set(SET_FLAG, srAdjIdFlags.isSetFlag());
91         flags.toByteBuf(value);
92         value.writeByte(srAdjId.getWeight().getValue());
93         TlvUtil.writeSrTLV(SID_TYPE, Unpooled.wrappedBuffer(srAdjId.getSid().getValue()), value);
94         return value;
95     }
96
97     public static SrLanAdjId parseLanAdjacencySegmentIdentifier(final ByteBuf buffer) {
98         if (!buffer.isReadable()) {
99             return new SrLanAdjIdBuilder().build();
100         }
101         final SrLanAdjIdBuilder srLanAdjIdBuilder = new SrLanAdjIdBuilder();
102         final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE);
103         srLanAdjIdBuilder.setFlags(new AdjacencyFlags(flags.get(ADDRESS_FAMILY_FLAG), flags.get(BACKUP_FLAG), flags.get(LOCAL_FLAG), flags.get(SET_FLAG), flags.get(VALUE_FLAG)));
104         srLanAdjIdBuilder.setWeight(new Weight(buffer.readUnsignedByte()));
105         srLanAdjIdBuilder.setIsoSystemId(new IsoSystemIdentifier(ByteArray.readBytes(buffer, ISO_SYSTEM_ID_SIZE)));
106         srLanAdjIdBuilder.setSid(new SidLabel(parseSidSubTlv(buffer)));
107         return srLanAdjIdBuilder.build();
108     }
109
110     private static SidLabel parseSidSubTlv(final ByteBuf buffer) {
111         final SidLabel sidValue;
112         final int type = buffer.readUnsignedByte();
113         final int length = buffer.readUnsignedByte();
114         sidValue = new SidLabel(ByteArray.readAllBytes(buffer.readSlice(length)));
115         if (type != SID_TYPE) {
116             LOG.warn("Unexpected type in SID/label Sub-TLV, expected {}, actual {}, ignoring it", SID_TYPE, type);
117             return null;
118         }
119         return sidValue;
120     }
121
122     public static ByteBuf serializeLanAdjacencySegmentIdentifier(final SrLanAdjId srLanAdjId) {
123         final ByteBuf value = Unpooled.buffer();
124         final AdjacencyFlags srAdjIdFlags = srLanAdjId.getFlags();
125         final BitArray flags = new BitArray(FLAGS_SIZE);
126         flags.set(ADDRESS_FAMILY_FLAG, srAdjIdFlags.isAddressFamily());
127         flags.set(BACKUP_FLAG, srAdjIdFlags.isBackup());
128         flags.set(VALUE_FLAG, srAdjIdFlags.isValue());
129         flags.set(LOCAL_FLAG, srAdjIdFlags.isLocal());
130         flags.set(SET_FLAG, srAdjIdFlags.isSetFlag());
131         flags.toByteBuf(value);
132         value.writeByte(srLanAdjId.getWeight().getValue());
133         value.writeBytes(srLanAdjId.getIsoSystemId().getValue());
134         TlvUtil.writeSrTLV(SID_TYPE, Unpooled.wrappedBuffer(srLanAdjId.getSid().getValue()), value);
135         return value;
136     }
137 }