433e52c0562f8c0fc57cb9a04c85492060ae1cb0
[bgpcep.git] / bgp / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / nlri / NodeNlriParser.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 com.google.common.primitives.UnsignedInteger;
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.TlvUtil;
15 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
16 import org.opendaylight.protocol.util.ByteArray;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.AreaIdentifier;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.DomainIdentifier;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.NodeIdentifier;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.OspfInterfaceIdentifier;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.isis.lan.identifier.IsIsRouterIdentifier;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.isis.lan.identifier.IsIsRouterIdentifierBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.linkstate.destination.c.linkstate.destination.LocalNodeDescriptorsBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.linkstate.destination.c.linkstate.destination.RemoteNodeDescriptorsBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.CRouterIdentifier;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.IsisNodeCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.IsisNodeCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.IsisPseudonodeCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.IsisPseudonodeCaseBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.OspfNodeCase;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.OspfNodeCaseBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.OspfPseudonodeCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.OspfPseudonodeCaseBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.isis.node._case.IsisNode;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.isis.node._case.IsisNodeBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.isis.pseudonode._case.IsisPseudonode;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.isis.pseudonode._case.IsisPseudonodeBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.ospf.node._case.OspfNodeBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.ospf.pseudonode._case.OspfPseudonode;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.node.identifier.c.router.identifier.ospf.pseudonode._case.OspfPseudonodeBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 final class NodeNlriParser {
47
48     private static final Logger LOG = LoggerFactory.getLogger(NodeNlriParser.class);
49
50     private static final int OSPF_PSEUDONODE_ROUTER_ID_LENGTH = 8;
51     private static final int OSPF_ROUTER_ID_LENGTH = 4;
52     private static final int ISO_SYSTEM_ID_LENGTH = 6;
53     private static final int PSN_LENGTH = 1;
54
55     /* Node Descriptor TLVs */
56     private static final int AS_NUMBER = 512;
57     private static final int BGP_LS_ID = 513;
58     private static final int AREA_ID = 514;
59     private static final int IGP_ROUTER_ID = 515;
60
61     static NodeIdentifier parseNodeDescriptors(final ByteBuf buffer, final boolean local) throws BGPParsingException {
62         AsNumber asnumber = null;
63         DomainIdentifier bgpId = null;
64         AreaIdentifier ai = null;
65         CRouterIdentifier routerId = null;
66         while (buffer.isReadable()) {
67             final int type = buffer.readUnsignedShort();
68             final int length = buffer.readUnsignedShort();
69             final ByteBuf value = buffer.slice(buffer.readerIndex(), length);
70             if (LOG.isTraceEnabled()) {
71                 LOG.trace("Parsing Node Descriptor: {}", ByteBufUtil.hexDump(value));
72             }
73             switch (type) {
74             case AS_NUMBER:
75                 asnumber = new AsNumber(value.readUnsignedInt());
76                 LOG.debug("Parsed {}", asnumber);
77                 break;
78             case BGP_LS_ID:
79                 bgpId = new DomainIdentifier(value.readUnsignedInt());
80                 LOG.debug("Parsed {}", bgpId);
81                 break;
82             case AREA_ID:
83                 ai = new AreaIdentifier(value.readUnsignedInt());
84                 LOG.debug("Parsed area identifier {}", ai);
85                 break;
86             case IGP_ROUTER_ID:
87                 routerId = parseRouterId(value);
88                 LOG.debug("Parsed Router Identifier {}", routerId);
89                 break;
90             default:
91                 throw new BGPParsingException("Node Descriptor not recognized, type: " + type);
92             }
93             buffer.skipBytes(length);
94         }
95         LOG.trace("Finished parsing Node descriptors.");
96         return (local) ? new LocalNodeDescriptorsBuilder().setAsNumber(asnumber).setDomainId(bgpId).setAreaId(ai).setCRouterIdentifier(
97             routerId).build()
98             : new RemoteNodeDescriptorsBuilder().setAsNumber(asnumber).setDomainId(bgpId).setAreaId(ai).setCRouterIdentifier(routerId).build();
99     }
100
101     private static CRouterIdentifier parseRouterId(final ByteBuf value) throws BGPParsingException {
102         if (value.readableBytes() == ISO_SYSTEM_ID_LENGTH || (value.readableBytes() == ISO_SYSTEM_ID_LENGTH + PSN_LENGTH && value.getByte(ISO_SYSTEM_ID_LENGTH) == 0)) {
103             return new IsisNodeCaseBuilder().setIsisNode(
104                 new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.readBytes(value, ISO_SYSTEM_ID_LENGTH))).build()).build();
105         }
106         if (value.readableBytes() == ISO_SYSTEM_ID_LENGTH + PSN_LENGTH) {
107             final IsIsRouterIdentifier iri = new IsIsRouterIdentifierBuilder().setIsoSystemId(
108                 new IsoSystemIdentifier(ByteArray.readBytes(value, ISO_SYSTEM_ID_LENGTH))).build();
109             return new IsisPseudonodeCaseBuilder().setIsisPseudonode(new IsisPseudonodeBuilder().setIsIsRouterIdentifier(iri).setPsn((short) value.readByte()).build()).build();
110         }
111         if (value.readableBytes() == OSPF_ROUTER_ID_LENGTH) {
112             return new OspfNodeCaseBuilder().setOspfNode(
113                 new OspfNodeBuilder().setOspfRouterId(value.readUnsignedInt()).build()).build();
114         }
115         if (value.readableBytes() == OSPF_PSEUDONODE_ROUTER_ID_LENGTH) {
116             return new OspfPseudonodeCaseBuilder().setOspfPseudonode(
117                 new OspfPseudonodeBuilder().setOspfRouterId(value.readUnsignedInt()).setLanInterface(new OspfInterfaceIdentifier(value.readUnsignedInt())).build()).build();
118         }
119         throw new BGPParsingException("Router Id of invalid length " + value.readableBytes());
120     }
121
122     static void serializeNodeDescriptors(final NodeIdentifier descriptors, final ByteBuf buffer) {
123         if (descriptors.getAsNumber() != null) {
124             TlvUtil.writeTLV(AS_NUMBER, Unpooled.copyInt(UnsignedInteger.valueOf(descriptors.getAsNumber().getValue()).intValue()), buffer);
125         }
126         if (descriptors.getDomainId() != null) {
127             TlvUtil.writeTLV(BGP_LS_ID, Unpooled.copyInt(UnsignedInteger.valueOf(descriptors.getDomainId().getValue()).intValue()), buffer);
128         }
129         if (descriptors.getAreaId() != null) {
130             TlvUtil.writeTLV(AREA_ID, Unpooled.copyInt(UnsignedInteger.valueOf(descriptors.getAreaId().getValue()).intValue()), buffer);
131         }
132         if (descriptors.getCRouterIdentifier() != null) {
133             final ByteBuf routerIdBuf = Unpooled.buffer();
134             serializeRouterId(descriptors.getCRouterIdentifier(), routerIdBuf);
135             TlvUtil.writeTLV(IGP_ROUTER_ID, routerIdBuf, buffer);
136         }
137     }
138
139     private static void serializeRouterId(final CRouterIdentifier routerId, final ByteBuf buffer) {
140         if (routerId instanceof IsisNodeCase) {
141             final IsisNode isis = ((IsisNodeCase) routerId).getIsisNode();
142             buffer.writeBytes(isis.getIsoSystemId().getValue());
143         } else if (routerId instanceof IsisPseudonodeCase) {
144             final IsisPseudonode isis = ((IsisPseudonodeCase) routerId).getIsisPseudonode();
145             buffer.writeBytes(isis.getIsIsRouterIdentifier().getIsoSystemId().getValue());
146             buffer.writeByte(((isis.getPsn() != null) ? isis.getPsn() : 0));
147         } else if (routerId instanceof OspfNodeCase) {
148             buffer.writeInt(UnsignedInteger.valueOf(((OspfNodeCase) routerId).getOspfNode().getOspfRouterId()).intValue());
149         } else if (routerId instanceof OspfPseudonodeCase) {
150             final OspfPseudonode node = ((OspfPseudonodeCase) routerId).getOspfPseudonode();
151             buffer.writeInt(UnsignedInteger.valueOf(node.getOspfRouterId()).intValue());
152             buffer.writeInt(UnsignedInteger.valueOf(node.getLanInterface().getValue()).intValue());
153         }
154     }
155 }