2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.linkstate.attribute;
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.bgp.linkstate.attribute.sr.SrNodeAttributesParser;
21 import org.opendaylight.protocol.util.ByteArray;
22 import org.opendaylight.protocol.util.Ipv4Util;
23 import org.opendaylight.protocol.util.Ipv6Util;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv4RouterIdentifier;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv6RouterIdentifier;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.IsisAreaIdentifier;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeFlagBits;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.TopologyIdentifier;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.state.SrAlgorithm;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.state.SrCapabilities;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.LinkStateAttribute;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributesCaseBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributes;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributesBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.rev150206.SidLabelBinding;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 final class NodeAttributesParser {
42 private static final Logger LOG = LoggerFactory.getLogger(NodeAttributesParser.class);
45 private static final int OVERLOAD_BIT = 7;
46 private static final int ATTACHED_BIT = 6;
47 private static final int EXTERNAL_BIT = 5;
48 private static final int ABBR_BIT = 4;
50 /* Node Attribute TLVs */
51 private static final int NODE_FLAG_BITS = 1024;
52 private static final int NODE_OPAQUE = 1025;
53 private static final int DYNAMIC_HOSTNAME = 1026;
54 private static final int ISIS_AREA_IDENTIFIER = 1027;
56 /* Segment routing TLVs */
57 private static final int SID_LABEL_BINDING = 1033;
58 private static final int SR_CAPABILITIES = 1034;
59 private static final int SR_ALGORITHMS = 1035;
62 * Parse Node Attributes.
64 * @param attributes key is the tlv type and value is the value of the tlv
65 * @return {@link LinkStateAttribute}
67 static LinkStateAttribute parseNodeAttributes(final Multimap<Integer, ByteBuf> attributes) {
68 final List<TopologyIdentifier> topologyMembership = new ArrayList<>();
69 final List<IsisAreaIdentifier> areaMembership = new ArrayList<>();
70 final NodeAttributesBuilder builder = new NodeAttributesBuilder();
71 for (final Entry<Integer, ByteBuf> entry : attributes.entries()) {
72 final int key = entry.getKey();
73 final ByteBuf value = entry.getValue();
74 LOG.trace("Node attribute TLV {}", key);
76 case TlvUtil.MULTI_TOPOLOGY_ID:
77 while (value.isReadable()) {
78 final TopologyIdentifier topId = new TopologyIdentifier(value.readUnsignedShort() & TlvUtil.TOPOLOGY_ID_OFFSET);
79 topologyMembership.add(topId);
80 LOG.debug("Parsed Topology Identifier: {}", topId);
84 final BitSet flags = BitSet.valueOf(ByteArray.readAllBytes(value));
85 builder.setNodeFlags(new NodeFlagBits(flags.get(OVERLOAD_BIT), flags.get(ATTACHED_BIT), flags.get(EXTERNAL_BIT), flags.get(ABBR_BIT)));
86 LOG.debug("Parsed Overload bit: {}, attached bit: {}, external bit: {}, area border router: {}.",
87 flags.get(OVERLOAD_BIT), flags.get(ATTACHED_BIT), flags.get(EXTERNAL_BIT), flags.get(ABBR_BIT));
90 if (LOG.isDebugEnabled()) {
91 LOG.debug("Ignoring opaque value: {}.", ByteBufUtil.hexDump(value));
94 case DYNAMIC_HOSTNAME:
95 builder.setDynamicHostname(new String(ByteArray.readAllBytes(value), Charsets.US_ASCII));
96 LOG.debug("Parsed Node Name {}", builder.getDynamicHostname());
98 case ISIS_AREA_IDENTIFIER:
99 final IsisAreaIdentifier ai = new IsisAreaIdentifier(ByteArray.readAllBytes(value));
100 areaMembership.add(ai);
101 LOG.debug("Parsed AreaIdentifier {}", ai);
103 case TlvUtil.LOCAL_IPV4_ROUTER_ID:
104 final Ipv4RouterIdentifier ip4 = new Ipv4RouterIdentifier(Ipv4Util.addressForByteBuf(value));
105 builder.setIpv4RouterId(ip4);
106 LOG.debug("Parsed IPv4 Router Identifier {}", ip4);
108 case TlvUtil.LOCAL_IPV6_ROUTER_ID:
109 final Ipv6RouterIdentifier ip6 = new Ipv6RouterIdentifier(Ipv6Util.addressForByteBuf(value));
110 builder.setIpv6RouterId(ip6);
111 LOG.debug("Parsed IPv6 Router Identifier {}", ip6);
113 case SID_LABEL_BINDING:
114 final SidLabelBinding label = SrNodeAttributesParser.parseSidLabelBinding(value);
116 LOG.debug("Parsed SID Label Binding {}", label);
118 case SR_CAPABILITIES:
119 final SrCapabilities caps = SrNodeAttributesParser.parseSrCapabilities(value);
120 builder.setSrCapabilities(caps);
121 LOG.debug("Parsed SR Capabilities {}", caps);
124 final SrAlgorithm algs = SrNodeAttributesParser.parseSrAlgorithms(value);
125 builder.setSrAlgorithm(algs);
126 LOG.debug("Parsed SR Algorithms {}", algs);
129 LOG.warn("TLV {} is not a valid node attribute, ignoring it", key);
132 LOG.trace("Finished parsing Node Attributes.");
133 builder.setTopologyIdentifier(topologyMembership);
134 builder.setIsisAreaId(areaMembership);
135 return new NodeAttributesCaseBuilder().setNodeAttributes(builder.build()).build();
138 static void serializeNodeAttributes(final NodeAttributesCase nodeAttributesCase, final ByteBuf byteAggregator) {
139 LOG.trace("Started serializing Node Attributes");
140 final NodeAttributes nodeAttributes = nodeAttributesCase.getNodeAttributes();
141 final List<TopologyIdentifier> topList = nodeAttributes.getTopologyIdentifier();
142 if (topList != null && !topList.isEmpty()) {
143 final ByteBuf mpIdBuf = Unpooled.buffer();
144 for (final TopologyIdentifier topologyIdentifier : topList) {
145 mpIdBuf.writeShort(topologyIdentifier.getValue());
147 TlvUtil.writeTLV(TlvUtil.MULTI_TOPOLOGY_ID, mpIdBuf, byteAggregator);
149 serializeNodeFlagBits(nodeAttributes.getNodeFlags(), byteAggregator);
150 if (nodeAttributes.getDynamicHostname() != null) {
151 TlvUtil.writeTLV(DYNAMIC_HOSTNAME, Unpooled.wrappedBuffer(Charsets.UTF_8.encode(nodeAttributes.getDynamicHostname())), byteAggregator);
153 final List<IsisAreaIdentifier> isisList = nodeAttributes.getIsisAreaId();
154 if (isisList != null && !isisList.isEmpty()) {
155 for (final IsisAreaIdentifier isisAreaIdentifier : isisList) {
156 TlvUtil.writeTLV(ISIS_AREA_IDENTIFIER, Unpooled.wrappedBuffer(isisAreaIdentifier.getValue()), byteAggregator);
159 if (nodeAttributes.getIpv4RouterId() != null) {
160 TlvUtil.writeTLV(TlvUtil.LOCAL_IPV4_ROUTER_ID, Ipv4Util.byteBufForAddress(nodeAttributes.getIpv4RouterId()), byteAggregator);
162 if (nodeAttributes.getIpv6RouterId() != null) {
163 TlvUtil.writeTLV(TlvUtil.LOCAL_IPV6_ROUTER_ID, Ipv6Util.byteBufForAddress(nodeAttributes.getIpv6RouterId()), byteAggregator);
165 LOG.trace("Finished serializing Node Attributes");
168 private static void serializeNodeFlagBits(final NodeFlagBits nodeFlagBits, final ByteBuf byteAggregator) {
169 if (nodeFlagBits != null) {
170 final ByteBuf nodeFlagBuf = Unpooled.buffer(1);
171 final BitSet flags = new BitSet(Byte.SIZE);
172 if (nodeFlagBits.isOverload() != null) {
173 flags.set(OVERLOAD_BIT, nodeFlagBits.isOverload());
175 if (nodeFlagBits.isAttached() != null) {
176 flags.set(ATTACHED_BIT, nodeFlagBits.isAttached());
178 if (nodeFlagBits.isExternal() != null) {
179 flags.set(EXTERNAL_BIT, nodeFlagBits.isExternal());
181 if (nodeFlagBits.isAbr() != null) {
182 flags.set(ABBR_BIT, nodeFlagBits.isAbr());
184 nodeFlagBuf.writeBytes(flags.toByteArray());
185 TlvUtil.writeTLV(NODE_FLAG_BITS, nodeFlagBuf, byteAggregator);