BUG-608 : added prefix-sid tlv
[bgpcep.git] / bgp / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / nlri / LinkNlriParser.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.nlri;
9
10 import io.netty.buffer.ByteBuf;
11 import io.netty.buffer.ByteBufUtil;
12 import io.netty.buffer.Unpooled;
13 import org.opendaylight.protocol.bgp.linkstate.TlvUtil;
14 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
15 import org.opendaylight.protocol.util.Ipv4Util;
16 import org.opendaylight.protocol.util.Ipv6Util;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv4InterfaceIdentifier;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Ipv6InterfaceIdentifier;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.TopologyIdentifier;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.c.linkstate.destination.LinkDescriptors;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.c.linkstate.destination.LinkDescriptorsBuilder;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 final class LinkNlriParser {
26
27     private static final Logger LOG = LoggerFactory.getLogger(LinkNlriParser.class);
28
29     /* Link Descriptor TLVs */
30     private static final int LINK_LR_IDENTIFIERS = 258;
31     private static final int IPV4_IFACE_ADDRESS = 259;
32     private static final int IPV4_NEIGHBOR_ADDRESS = 260;
33     private static final int IPV6_IFACE_ADDRESS = 261;
34     private static final int IPV6_NEIGHBOR_ADDRESS = 262;
35
36     static LinkDescriptors parseLinkDescriptors(final ByteBuf buffer) throws BGPParsingException {
37         final LinkDescriptorsBuilder builder = new LinkDescriptorsBuilder();
38         while (buffer.isReadable()) {
39             final int type = buffer.readUnsignedShort();
40             final int length = buffer.readUnsignedShort();
41             final ByteBuf value = buffer.slice(buffer.readerIndex(), length);
42             LOG.trace("Parsing Link Descriptor: {}", ByteBufUtil.hexDump(value));
43             switch (type) {
44             case LINK_LR_IDENTIFIERS:
45                 builder.setLinkLocalIdentifier(value.readUnsignedInt());
46                 builder.setLinkRemoteIdentifier(value.readUnsignedInt());
47                 LOG.debug("Parsed link local {} remote {} Identifiers.", builder.getLinkLocalIdentifier(),
48                     builder.getLinkRemoteIdentifier());
49                 break;
50             case IPV4_IFACE_ADDRESS:
51                 final Ipv4InterfaceIdentifier lipv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForByteBuf(value));
52                 builder.setIpv4InterfaceAddress(lipv4);
53                 LOG.debug("Parsed IPv4 interface address {}.", lipv4);
54                 break;
55             case IPV4_NEIGHBOR_ADDRESS:
56                 final Ipv4InterfaceIdentifier ripv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForByteBuf(value));
57                 builder.setIpv4NeighborAddress(ripv4);
58                 LOG.debug("Parsed IPv4 neighbor address {}.", ripv4);
59                 break;
60             case IPV6_IFACE_ADDRESS:
61                 final Ipv6InterfaceIdentifier lipv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForByteBuf(value));
62                 builder.setIpv6InterfaceAddress(lipv6);
63                 LOG.debug("Parsed IPv6 interface address {}.", lipv6);
64                 break;
65             case IPV6_NEIGHBOR_ADDRESS:
66                 final Ipv6InterfaceIdentifier ripv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForByteBuf(value));
67                 builder.setIpv6NeighborAddress(ripv6);
68                 LOG.debug("Parsed IPv6 neighbor address {}.", ripv6);
69                 break;
70             case TlvUtil.MULTI_TOPOLOGY_ID:
71                 final TopologyIdentifier topId = new TopologyIdentifier(value.readUnsignedShort() & TlvUtil.TOPOLOGY_ID_OFFSET);
72                 builder.setMultiTopologyId(topId);
73                 LOG.debug("Parsed topology identifier {}.", topId);
74                 break;
75             default:
76                 throw new BGPParsingException("Link Descriptor not recognized, type: " + type);
77             }
78             buffer.skipBytes(length);
79         }
80         LOG.trace("Finished parsing Link descriptors.");
81         return builder.build();
82     }
83
84     static void serializeLinkDescriptors(final LinkDescriptors descriptors, final ByteBuf buffer) {
85         if (descriptors.getLinkLocalIdentifier() != null && descriptors.getLinkRemoteIdentifier() != null) {
86             final ByteBuf identifierBuf = Unpooled.buffer();
87             identifierBuf.writeInt(descriptors.getLinkLocalIdentifier().intValue());
88             identifierBuf.writeInt(descriptors.getLinkRemoteIdentifier().intValue());
89             TlvUtil.writeTLV(LINK_LR_IDENTIFIERS, identifierBuf, buffer);
90         }
91         if (descriptors.getIpv4InterfaceAddress() != null) {
92             TlvUtil.writeTLV(IPV4_IFACE_ADDRESS, Ipv4Util.byteBufForAddress(descriptors.getIpv4InterfaceAddress()), buffer);
93         }
94         if (descriptors.getIpv4NeighborAddress() != null) {
95             TlvUtil.writeTLV(IPV4_NEIGHBOR_ADDRESS, Ipv4Util.byteBufForAddress(descriptors.getIpv4NeighborAddress()), buffer);
96         }
97         if (descriptors.getIpv6InterfaceAddress() != null) {
98             TlvUtil.writeTLV(IPV6_IFACE_ADDRESS, Ipv6Util.byteBufForAddress(descriptors.getIpv6InterfaceAddress()), buffer);
99         }
100         if (descriptors.getIpv6NeighborAddress() != null) {
101             TlvUtil.writeTLV(IPV6_NEIGHBOR_ADDRESS, Ipv6Util.byteBufForAddress(descriptors.getIpv6NeighborAddress()), buffer);
102         }
103         if (descriptors.getMultiTopologyId() != null) {
104             TlvUtil.writeTLV(TlvUtil.MULTI_TOPOLOGY_ID, Unpooled.copyShort(descriptors.getMultiTopologyId().getValue()), buffer);
105         }
106     }
107 }