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.nlri;
10 import com.google.common.annotations.VisibleForTesting;
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.ByteBufUtil;
13 import io.netty.buffer.Unpooled;
14 import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
15 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
16 import org.opendaylight.protocol.util.Ipv4Util;
17 import org.opendaylight.protocol.util.Ipv6Util;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv4InterfaceIdentifier;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv6InterfaceIdentifier;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NlriType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.TopologyIdentifier;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.ObjectType;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestination;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LinkDescriptors;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LinkDescriptorsBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LocalNodeDescriptors;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.RemoteNodeDescriptors;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
32 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 public final class LinkNlriParser implements NlriTypeCaseParser, NlriTypeCaseSerializer {
39 private static final Logger LOG = LoggerFactory.getLogger(LinkNlriParser.class);
41 /* Link Descriptor TLVs */
42 private static final int LINK_LR_IDENTIFIERS = 258;
43 private static final int IPV4_IFACE_ADDRESS = 259;
44 private static final int IPV4_NEIGHBOR_ADDRESS = 260;
45 private static final int IPV6_IFACE_ADDRESS = 261;
46 private static final int IPV6_NEIGHBOR_ADDRESS = 262;
48 /* Node Descriptor Type */
49 private static final int LOCAL_NODE_DESCRIPTORS_TYPE = 256;
50 private static final int REMOTE_NODE_DESCRIPTORS_TYPE = 257;
53 /* Link Descriptor QNames */
55 public static final NodeIdentifier IPV4_IFACE_NID = new NodeIdentifier(QName.create(LinkDescriptors.QNAME, "ipv4-interface-address").intern());
56 private static final NodeIdentifier IPV6_IFACE_NID = new NodeIdentifier(QName.create(LinkDescriptors.QNAME, "ipv6-interface-address").intern());
58 public static final NodeIdentifier IPV4_NEIGHBOR_NID = new NodeIdentifier(QName.create(LinkDescriptors.QNAME, "ipv4-neighbor-address").intern());
59 private static final NodeIdentifier IPV6_NEIGHBOR_NID = new NodeIdentifier(QName.create(LinkDescriptors.QNAME, "ipv6-neighbor-address").intern());
61 public static final NodeIdentifier LINK_LOCAL_NID = new NodeIdentifier(QName.create(LinkDescriptors.QNAME, "link-local-identifier").intern());
63 public static final NodeIdentifier LINK_REMOTE_NID = new NodeIdentifier(QName.create(LinkDescriptors.QNAME, "link-remote-identifier").intern());
65 static LinkDescriptors parseLinkDescriptors(final ByteBuf buffer) throws BGPParsingException {
66 final LinkDescriptorsBuilder builder = new LinkDescriptorsBuilder();
67 while (buffer.isReadable()) {
68 final int type = buffer.readUnsignedShort();
69 final int length = buffer.readUnsignedShort();
70 final ByteBuf value = buffer.readSlice(length);
71 LOG.trace("Parsing Link Descriptor: {}", ByteBufUtil.hexDump(value));
73 case LINK_LR_IDENTIFIERS:
74 builder.setLinkLocalIdentifier(value.readUnsignedInt());
75 builder.setLinkRemoteIdentifier(value.readUnsignedInt());
76 LOG.debug("Parsed link local {} remote {} Identifiers.", builder.getLinkLocalIdentifier(),
77 builder.getLinkRemoteIdentifier());
79 case IPV4_IFACE_ADDRESS:
80 final Ipv4InterfaceIdentifier lipv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForByteBuf(value));
81 builder.setIpv4InterfaceAddress(lipv4);
82 LOG.debug("Parsed IPv4 interface address {}.", lipv4);
84 case IPV4_NEIGHBOR_ADDRESS:
85 final Ipv4InterfaceIdentifier ripv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForByteBuf(value));
86 builder.setIpv4NeighborAddress(ripv4);
87 LOG.debug("Parsed IPv4 neighbor address {}.", ripv4);
89 case IPV6_IFACE_ADDRESS:
90 final Ipv6InterfaceIdentifier lipv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForByteBuf(value));
91 builder.setIpv6InterfaceAddress(lipv6);
92 LOG.debug("Parsed IPv6 interface address {}.", lipv6);
94 case IPV6_NEIGHBOR_ADDRESS:
95 final Ipv6InterfaceIdentifier ripv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForByteBuf(value));
96 builder.setIpv6NeighborAddress(ripv6);
97 LOG.debug("Parsed IPv6 neighbor address {}.", ripv6);
99 case TlvUtil.MULTI_TOPOLOGY_ID:
100 final TopologyIdentifier topId = new TopologyIdentifier(value.readUnsignedShort() & TlvUtil.TOPOLOGY_ID_OFFSET);
101 builder.setMultiTopologyId(topId);
102 LOG.debug("Parsed topology identifier {}.", topId);
105 throw new BGPParsingException("Link Descriptor not recognized, type: " + type);
108 LOG.trace("Finished parsing Link descriptors.");
109 return builder.build();
112 static void serializeLinkDescriptors(final LinkDescriptors descriptors, final ByteBuf buffer) {
113 if (descriptors.getLinkLocalIdentifier() != null && descriptors.getLinkRemoteIdentifier() != null) {
114 final ByteBuf identifierBuf = Unpooled.buffer();
115 identifierBuf.writeInt(descriptors.getLinkLocalIdentifier().intValue());
116 identifierBuf.writeInt(descriptors.getLinkRemoteIdentifier().intValue());
117 TlvUtil.writeTLV(LINK_LR_IDENTIFIERS, identifierBuf, buffer);
119 if (descriptors.getIpv4InterfaceAddress() != null) {
120 TlvUtil.writeTLV(IPV4_IFACE_ADDRESS, Ipv4Util.byteBufForAddress(descriptors.getIpv4InterfaceAddress()), buffer);
122 if (descriptors.getIpv4NeighborAddress() != null) {
123 TlvUtil.writeTLV(IPV4_NEIGHBOR_ADDRESS, Ipv4Util.byteBufForAddress(descriptors.getIpv4NeighborAddress()), buffer);
125 if (descriptors.getIpv6InterfaceAddress() != null) {
126 TlvUtil.writeTLV(IPV6_IFACE_ADDRESS, Ipv6Util.byteBufForAddress(descriptors.getIpv6InterfaceAddress()), buffer);
128 if (descriptors.getIpv6NeighborAddress() != null) {
129 TlvUtil.writeTLV(IPV6_NEIGHBOR_ADDRESS, Ipv6Util.byteBufForAddress(descriptors.getIpv6NeighborAddress()), buffer);
131 if (descriptors.getMultiTopologyId() != null) {
132 TlvUtil.writeTLV(TlvUtil.MULTI_TOPOLOGY_ID, Unpooled.copyShort(descriptors.getMultiTopologyId().getValue()), buffer);
136 static LinkDescriptors serializeLinkDescriptors(final ContainerNode descriptors) {
137 final LinkDescriptorsBuilder linkDescBuilder = new LinkDescriptorsBuilder();
139 if (descriptors.getChild(LINK_LOCAL_NID).isPresent() && descriptors.getChild(LINK_REMOTE_NID).isPresent()) {
140 linkDescBuilder.setLinkLocalIdentifier((Long) descriptors.getChild(LINK_LOCAL_NID).get().getValue());
141 linkDescBuilder.setLinkRemoteIdentifier((Long) descriptors.getChild(LINK_REMOTE_NID).get().getValue());
143 if (descriptors.getChild(IPV4_IFACE_NID).isPresent()) {
144 linkDescBuilder.setIpv4InterfaceAddress(new Ipv4InterfaceIdentifier((String) descriptors.getChild(IPV4_IFACE_NID).get().getValue()));
146 if (descriptors.getChild(IPV6_IFACE_NID).isPresent()) {
147 linkDescBuilder.setIpv6InterfaceAddress(new Ipv6InterfaceIdentifier((String) descriptors.getChild(IPV6_IFACE_NID).get().getValue()));
149 if (descriptors.getChild(IPV4_NEIGHBOR_NID).isPresent()) {
150 linkDescBuilder.setIpv4NeighborAddress(new Ipv4InterfaceIdentifier((String) descriptors.getChild(IPV4_NEIGHBOR_NID).get().getValue()));
152 if (descriptors.getChild(IPV6_NEIGHBOR_NID).isPresent()) {
153 linkDescBuilder.setIpv6NeighborAddress(new Ipv6InterfaceIdentifier((String) descriptors.getChild(IPV6_NEIGHBOR_NID).get().getValue()));
155 if (descriptors.getChild(TlvUtil.MULTI_TOPOLOGY_NID).isPresent()) {
156 linkDescBuilder.setMultiTopologyId(new TopologyIdentifier((Integer) descriptors.getChild(TlvUtil.MULTI_TOPOLOGY_NID).get().getValue()));
158 return linkDescBuilder.build();
163 public ObjectType parseTypeNlri(final ByteBuf nlri, final NlriType type, final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeIdentifier localdescriptor, final ByteBuf restNlri) throws BGPParsingException {
165 final int nodetype = restNlri.readUnsignedShort();
166 final int length = restNlri.readUnsignedShort();
168 RemoteNodeDescriptors remoteDescriptors = null;
170 if (nodetype == REMOTE_NODE_DESCRIPTORS_TYPE) {
171 remoteDescriptors = (RemoteNodeDescriptors) NodeNlriParser.parseNodeDescriptors(restNlri.readSlice(length), type, false);
173 LinkDescriptors linkdescriptor = parseLinkDescriptors(restNlri.slice());
174 LinkCaseBuilder linkbuilder = new LinkCaseBuilder();
175 LinkCase linkcase = linkbuilder.setLocalNodeDescriptors((LocalNodeDescriptors) localdescriptor).setRemoteNodeDescriptors(remoteDescriptors).setLinkDescriptors(linkdescriptor).build();
180 public NlriType serializeTypeNlri(final CLinkstateDestination destination, final ByteBuf localdescs, final ByteBuf byteAggregator) {
182 final LinkCase lCase = ((LinkCase)destination.getObjectType());
183 NodeNlriParser.serializeNodeIdentifier(lCase.getLocalNodeDescriptors(), localdescs);
184 NodeNlriParser.serializeEpeNodeDescriptors(lCase.getLocalNodeDescriptors(), localdescs);
185 TlvUtil.writeTLV(LOCAL_NODE_DESCRIPTORS_TYPE, localdescs, byteAggregator);
186 final ByteBuf rdescs = Unpooled.buffer();
187 NodeNlriParser.serializeNodeIdentifier(lCase.getRemoteNodeDescriptors(), rdescs);
188 NodeNlriParser.serializeEpeNodeDescriptors(lCase.getRemoteNodeDescriptors(), rdescs);
189 TlvUtil.writeTLV(REMOTE_NODE_DESCRIPTORS_TYPE, rdescs, byteAggregator);
190 if (lCase.getLinkDescriptors() != null) {
191 LinkNlriParser.serializeLinkDescriptors(lCase.getLinkDescriptors(), byteAggregator);
193 return NlriType.Link;