b893c794b8c797675e0985473d9c861442aef6a8
[bgpcep.git] / bgp / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / attribute / NodeAttributesParser.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;
9
10 import com.google.common.base.Charsets;
11 import com.google.common.collect.Multimap;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.ByteBufUtil;
14 import io.netty.buffer.Unpooled;
15 import java.util.ArrayList;
16 import java.util.BitSet;
17 import java.util.List;
18 import java.util.Map.Entry;
19 import org.opendaylight.protocol.bgp.linkstate.TlvUtil;
20 import org.opendaylight.protocol.util.ByteArray;
21 import org.opendaylight.protocol.util.Ipv4Util;
22 import org.opendaylight.protocol.util.Ipv6Util;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.Ipv4RouterIdentifier;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.Ipv6RouterIdentifier;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.IsisAreaIdentifier;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.NodeFlagBits;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.TopologyIdentifier;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.LinkStateAttribute;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributesCaseBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributes;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributesBuilder;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 final class NodeAttributesParser {
37
38     private static final Logger LOG = LoggerFactory.getLogger(NodeAttributesParser.class);
39
40     // node flag bits
41     private static final int OVERLOAD_BIT = 7;
42     private static final int ATTACHED_BIT = 6;
43     private static final int EXTERNAL_BIT = 5;
44     private static final int ABBR_BIT = 4;
45
46     /* Node Attribute TLVs */
47     private static final int NODE_FLAG_BITS = 1024;
48     private static final int NODE_OPAQUE = 1025;
49     private static final int DYNAMIC_HOSTNAME = 1026;
50     private static final int ISIS_AREA_IDENTIFIER = 1027;
51
52     /**
53      * Parse Node Attributes.
54      *
55      * @param attributes key is the tlv type and value is the value of the tlv
56      * @return {@link LinkStateAttribute}
57      */
58     static LinkStateAttribute parseNodeAttributes(final Multimap<Integer, ByteBuf> attributes) {
59         final List<TopologyIdentifier> topologyMembership = new ArrayList<>();
60         final List<IsisAreaIdentifier> areaMembership = new ArrayList<>();
61         final NodeAttributesBuilder builder = new NodeAttributesBuilder();
62         for (final Entry<Integer, ByteBuf> entry : attributes.entries()) {
63             final int key = entry.getKey();
64             final ByteBuf value = entry.getValue();
65             LOG.trace("Node attribute TLV {}", key);
66             switch (key) {
67             case TlvUtil.MULTI_TOPOLOGY_ID:
68                 while (value.isReadable()) {
69                     final TopologyIdentifier topId = new TopologyIdentifier(value.readUnsignedShort() & TlvUtil.TOPOLOGY_ID_OFFSET);
70                     topologyMembership.add(topId);
71                     LOG.debug("Parsed Topology Identifier: {}", topId);
72                 }
73                 break;
74             case NODE_FLAG_BITS:
75                 final BitSet flags = BitSet.valueOf(ByteArray.readAllBytes(value));
76                 builder.setNodeFlags(new NodeFlagBits(flags.get(OVERLOAD_BIT), flags.get(ATTACHED_BIT), flags.get(EXTERNAL_BIT), flags.get(ABBR_BIT)));
77                 LOG.debug("Parsed Overload bit: {}, attached bit: {}, external bit: {}, area border router: {}.",
78                     flags.get(OVERLOAD_BIT), flags.get(ATTACHED_BIT), flags.get(EXTERNAL_BIT), flags.get(ABBR_BIT));
79                 break;
80             case NODE_OPAQUE:
81                 if (LOG.isDebugEnabled()) {
82                     LOG.debug("Ignoring opaque value: {}.", ByteBufUtil.hexDump(value));
83                 }
84                 break;
85             case DYNAMIC_HOSTNAME:
86                 builder.setDynamicHostname(new String(ByteArray.readAllBytes(value), Charsets.US_ASCII));
87                 LOG.debug("Parsed Node Name {}", builder.getDynamicHostname());
88                 break;
89             case ISIS_AREA_IDENTIFIER:
90                 final IsisAreaIdentifier ai = new IsisAreaIdentifier(ByteArray.readAllBytes(value));
91                 areaMembership.add(ai);
92                 LOG.debug("Parsed AreaIdentifier {}", ai);
93                 break;
94             case TlvUtil.LOCAL_IPV4_ROUTER_ID:
95                 final Ipv4RouterIdentifier ip4 = new Ipv4RouterIdentifier(Ipv4Util.addressForByteBuf(value));
96                 builder.setIpv4RouterId(ip4);
97                 LOG.debug("Parsed IPv4 Router Identifier {}", ip4);
98                 break;
99             case TlvUtil.LOCAL_IPV6_ROUTER_ID:
100                 final Ipv6RouterIdentifier ip6 = new Ipv6RouterIdentifier(Ipv6Util.addressForByteBuf(value));
101                 builder.setIpv6RouterId(ip6);
102                 LOG.debug("Parsed IPv6 Router Identifier {}", ip6);
103                 break;
104             default:
105                 LOG.warn("TLV {} is not a valid node attribute, ignoring it", key);
106             }
107         }
108         LOG.trace("Finished parsing Node Attributes.");
109         builder.setTopologyIdentifier(topologyMembership);
110         builder.setIsisAreaId(areaMembership);
111         return new NodeAttributesCaseBuilder().setNodeAttributes(builder.build()).build();
112     }
113
114     static void serializeNodeAttributes(final NodeAttributesCase nodeAttributesCase, final ByteBuf byteAggregator) {
115         LOG.trace("Started serializing Node Attributes");
116         final NodeAttributes nodeAttributes = nodeAttributesCase.getNodeAttributes();
117         final List<TopologyIdentifier> topList = nodeAttributes.getTopologyIdentifier();
118         if (topList != null && !topList.isEmpty()) {
119             final ByteBuf mpIdBuf = Unpooled.buffer();
120             for (final TopologyIdentifier topologyIdentifier : topList) {
121                 mpIdBuf.writeShort(topologyIdentifier.getValue());
122             }
123             TlvUtil.writeTLV(TlvUtil.MULTI_TOPOLOGY_ID, mpIdBuf, byteAggregator);
124         }
125         serializeNodeFlagBits(nodeAttributes.getNodeFlags(), byteAggregator);
126         if (nodeAttributes.getDynamicHostname() != null) {
127             TlvUtil.writeTLV(DYNAMIC_HOSTNAME, Unpooled.wrappedBuffer(Charsets.UTF_8.encode(nodeAttributes.getDynamicHostname())), byteAggregator);
128         }
129         final List<IsisAreaIdentifier> isisList = nodeAttributes.getIsisAreaId();
130         if (isisList != null && !isisList.isEmpty()) {
131             for (final IsisAreaIdentifier isisAreaIdentifier : isisList) {
132                 TlvUtil.writeTLV(ISIS_AREA_IDENTIFIER, Unpooled.wrappedBuffer(isisAreaIdentifier.getValue()), byteAggregator);
133             }
134         }
135         if (nodeAttributes.getIpv4RouterId() != null) {
136             TlvUtil.writeTLV(TlvUtil.LOCAL_IPV4_ROUTER_ID, Ipv4Util.byteBufForAddress(nodeAttributes.getIpv4RouterId()), byteAggregator);
137         }
138         if (nodeAttributes.getIpv6RouterId() != null) {
139             TlvUtil.writeTLV(TlvUtil.LOCAL_IPV6_ROUTER_ID, Ipv6Util.byteBufForAddress(nodeAttributes.getIpv6RouterId()), byteAggregator);
140         }
141         LOG.trace("Finished serializing Node Attributes");
142     }
143
144     private static void serializeNodeFlagBits(final NodeFlagBits nodeFlagBits, final ByteBuf byteAggregator) {
145         if (nodeFlagBits != null) {
146             final ByteBuf nodeFlagBuf = Unpooled.buffer(1);
147             final BitSet flags = new BitSet(Byte.SIZE);
148             if (nodeFlagBits.isOverload() != null) {
149                 flags.set(OVERLOAD_BIT, nodeFlagBits.isOverload());
150             }
151             if (nodeFlagBits.isAttached() != null) {
152                 flags.set(ATTACHED_BIT, nodeFlagBits.isAttached());
153             }
154             if (nodeFlagBits.isExternal() != null) {
155                 flags.set(EXTERNAL_BIT, nodeFlagBits.isExternal());
156             }
157             if (nodeFlagBits.isAbr() != null) {
158                 flags.set(ABBR_BIT, nodeFlagBits.isAbr());
159             }
160             nodeFlagBuf.writeBytes(flags.toByteArray());
161             TlvUtil.writeTLV(NODE_FLAG_BITS, nodeFlagBuf, byteAggregator);
162         }
163     }
164 }