2 * Copyright (c) 2020 Orange. 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.bgpcep.bgp.topology.provider;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.base.Preconditions;
14 import java.math.BigDecimal;
15 import java.net.Inet4Address;
16 import java.net.Inet6Address;
17 import java.net.UnknownHostException;
18 import java.nio.ByteBuffer;
19 import java.util.ArrayList;
20 import java.util.List;
21 import org.opendaylight.graph.ConnectedGraph;
22 import org.opendaylight.graph.ConnectedGraphProvider;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
25 import org.opendaylight.protocol.bgp.rib.RibReference;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateAddressFamily;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateSubsequentAddressFamily;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.bgp.rib.rib.loc.rib.tables.routes.LinkstateRoutesCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.ObjectType;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.SrAdjIds;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.LinkCase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.NodeCase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.PrefixCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LinkDescriptors;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.LinkStateAttribute;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.link.attributes._case.LinkAttributes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributes;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributes;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.LinkstateRoutes;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRoute;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.linkstate.route.Attributes1;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.CRouterIdentifier;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.IsisNodeCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.OspfNodeCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.adj.flags.flags.isis.adj.flags._case.IsisAdjFlags;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.adj.flags.flags.ospf.adj.flags._case.OspfAdjFlags;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.prefix.sid.tlv.flags.IsisPrefixFlagsCase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.LocalLabelCase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.SidCase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.DecimalBandwidth;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Delay;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Loss;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Vertex.VertexType;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributes;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.MinMaxDelay;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.MinMaxDelayBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidth;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidthBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidthKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.Graph.DomainScope;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Edge;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.PrefixBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Vertex;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.vertex.SrgbBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.TopologyTypes1Builder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.bgp.linkstate.topology.type.BgpLinkstateTopologyBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.SrlgId;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
87 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
88 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
89 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
90 import org.opendaylight.yangtools.yang.common.Uint32;
91 import org.opendaylight.yangtools.yang.common.Uint64;
92 import org.slf4j.Logger;
93 import org.slf4j.LoggerFactory;
96 * This Class build the Traffic Engineering Database as a Connected Graph
97 * suitable to be used latter by Path Computation algorithms to compute end to
100 * @author Olivier Dugeon
101 * @author Philippe Niger
105 public class LinkstateGraphBuilder extends AbstractTopologyBuilder<LinkstateRoute> {
106 private static final TopologyTypes LINKSTATE_TOPOLOGY_TYPE = new TopologyTypesBuilder().addAugmentation(
107 new TopologyTypes1Builder().setBgpLinkstateTopology(new BgpLinkstateTopologyBuilder().build()).build())
110 private static final String UNHANDLED_OBJECT_CLASS = "Unhandled object class {}";
112 private static final Logger LOG = LoggerFactory.getLogger(LinkstateGraphBuilder.class);
114 private final ConnectedGraphProvider graphProvider;
115 private final ConnectedGraph cgraph;
117 public LinkstateGraphBuilder(final DataBroker dataProvider, final RibReference locRibReference,
118 final TopologyId topologyId, final ConnectedGraphProvider provider) {
119 super(dataProvider, locRibReference, topologyId, LINKSTATE_TOPOLOGY_TYPE, LinkstateAddressFamily.class,
120 LinkstateSubsequentAddressFamily.class);
121 this.graphProvider = requireNonNull(provider);
122 this.cgraph = provider.createConnectedGraph("ted://" + topologyId.getValue(),
123 DomainScope.IntraDomain);
124 /* LinkStateGraphBuilder doesn't write information in the Network Topology tree of the Data Store.
125 * This is performed by ConnectedGraphProvider which write element in Graph tree of the Data Store */
126 this.networkTopologyTransaction = false;
127 LOG.info("Started Traffic Engineering Graph Builder");
131 LinkstateGraphBuilder(final DataBroker dataProvider, final RibReference locRibReference,
132 final TopologyId topologyId, final ConnectedGraphProvider provider, final long listenerResetLimitInMillsec,
133 final int listenerResetEnforceCounter) {
134 super(dataProvider, locRibReference, topologyId, LINKSTATE_TOPOLOGY_TYPE, LinkstateAddressFamily.class,
135 LinkstateSubsequentAddressFamily.class, listenerResetLimitInMillsec, listenerResetEnforceCounter);
136 this.graphProvider = requireNonNull(provider);
137 this.cgraph = provider.createConnectedGraph("ted://" + topologyId.getValue(),
138 DomainScope.IntraDomain);
139 /* LinkStateGraphBuilder doesn't write information in the Network Topology tree of the Data Store.
140 * This is performed by ConnectedGraphProvider which write element in Graph tree of the Data Store */
141 this.networkTopologyTransaction = false;
142 LOG.info("Started Traffic Engineering Graph Builder");
146 protected void createObject(final ReadWriteTransaction trans, final InstanceIdentifier<LinkstateRoute> id,
147 final LinkstateRoute value) {
148 final ObjectType t = value.getObjectType();
149 Preconditions.checkArgument(t != null, "Route %s value %s has null object type", id, value);
151 if (t instanceof LinkCase) {
152 createEdge(value, (LinkCase) t, value.getAttributes());
153 } else if (t instanceof NodeCase) {
154 createVertex(value, (NodeCase) t, value.getAttributes());
155 } else if (t instanceof PrefixCase) {
156 createPrefix(value, (PrefixCase) t, value.getAttributes());
158 LOG.debug(UNHANDLED_OBJECT_CLASS, t.implementedInterface());
163 * Verify that mandatory information (Local & Remote Node and Link
164 * descriptors) are present in the link.
166 * @param linkCase The Link part of the Linkstate route
168 * @return True if all information are present, false otherwise
170 private static boolean checkLinkState(final LinkCase linkCase) {
171 if (linkCase.getLocalNodeDescriptors() == null || linkCase.getRemoteNodeDescriptors() == null) {
172 LOG.warn("Missing Local or Remote Node descriptor in link {}, skipping it", linkCase);
175 if (linkCase.getLinkDescriptors() == null) {
176 LOG.warn("Missing Link descriptor in link {}, skipping it", linkCase);
183 * Get Link attributes from the Link State route.
185 * @param attributes Link State Route Attributes
187 * @return Link Attributes
189 private static LinkAttributes getLinkAttributes(final Attributes attributes) {
190 final LinkAttributes la;
191 final Attributes1 attr = attributes.augmentation(Attributes1.class);
193 final LinkStateAttribute attrType = attr.getLinkStateAttribute();
194 if (attrType != null) {
195 la = ((LinkAttributesCase) attrType).getLinkAttributes();
206 * Determine the Source Edge Key from the link descriptor.
207 * There is several case: IPv4, IPv6 address or Unnumbered Interface.
209 * @param linkCase The Link part of the Linkstate route
213 private static Uint64 getEdgeId(final LinkCase linkCase) {
215 if (linkCase.getLinkDescriptors().getIpv4InterfaceAddress() != null) {
216 key = ipv4ToKey(linkCase.getLinkDescriptors().getIpv4InterfaceAddress().getValue());
218 if (linkCase.getLinkDescriptors().getIpv6InterfaceAddress() != null) {
219 key = ipv6ToKey(linkCase.getLinkDescriptors().getIpv6InterfaceAddress().getValue());
221 if (linkCase.getLinkDescriptors().getLinkLocalIdentifier() != null) {
222 key = linkCase.getLinkDescriptors().getLinkLocalIdentifier().longValue();
224 return Uint64.valueOf(key);
228 * Create new Connected Edge in the Connected Graph.
230 * @param value The complete Linkstate route information
231 * @param linkCase The Link part of the Linkstate route
232 * @param attributes The Link attributes
235 private void createEdge(final LinkstateRoute value, final LinkCase linkCase, final Attributes attributes) {
236 Preconditions.checkArgument(checkLinkState(linkCase), "Missing mandatory information in link {}", linkCase);
238 final LinkAttributes la = getLinkAttributes(attributes);
240 LOG.warn("Missing attributes in link {} route {}, skipping it", linkCase, value);
244 /* Get Source and Destination Vertex from the graph */
245 Uint64 srcId = getVertexId(linkCase.getLocalNodeDescriptors().getCRouterIdentifier());
246 Uint64 dstId = getVertexId(linkCase.getRemoteNodeDescriptors().getCRouterIdentifier());
247 if (srcId == Uint64.ZERO || dstId == Uint64.ZERO) {
248 LOG.warn("Unable to get the Source or Destination Vertex Identifier from link {}, skipping it", linkCase);
252 /* Get Source and Destination Key for the corresponding Edge */
253 Uint64 edgeId = getEdgeId(linkCase);
254 if (edgeId == Uint64.ZERO) {
255 LOG.warn("Unable to get the Edge Identifier from link {}, skipping it", linkCase);
259 /* Add associated Edge */
260 Edge edge = new EdgeBuilder().setEdgeId(edgeId).setLocalVertexId(srcId).setRemoteVertexId(dstId)
261 .setName(srcId + " - " + dstId)
262 .setEdgeAttributes(createEdgeAttributes(la, linkCase.getLinkDescriptors())).build();
265 * Add corresponding Prefix for the Local Address. Remote address will be added with the remote Edge */
266 PrefixBuilder prefBuilder = new PrefixBuilder().setVertexId(srcId);
267 if (edge.getEdgeAttributes().getLocalAddress().getIpv4Address() != null) {
268 prefBuilder.setPrefix(new IpPrefix(
269 new Ipv4Prefix(edge.getEdgeAttributes().getLocalAddress().getIpv4Address().getValue() + "/32")));
271 if (edge.getEdgeAttributes().getLocalAddress().getIpv6Address() != null) {
272 prefBuilder.setPrefix(new IpPrefix(
273 new Ipv6Prefix(edge.getEdgeAttributes().getLocalAddress().getIpv6Address().getValue() + "/128")));
275 Prefix prefix = prefBuilder.build();
277 /* Add the Edge in the Connected Graph */
278 LOG.info("Add Edge {} and associated Prefix {} in TED[{}]", edge.getName(), prefix.getPrefix(), cgraph);
279 cgraph.addEdge(edge);
280 cgraph.addPrefix(prefix);
283 private static final int MAX_PRIORITY = 8;
286 * Create Edge Attributes from Link attributes.
288 * @param la Linkstate Attributes
289 * @param linkDesc Linkstate Descriptors
291 * @return EdgeAttributes
293 private static EdgeAttributes createEdgeAttributes(final LinkAttributes la, final LinkDescriptors linkDesc) {
294 EdgeAttributesBuilder builder = new EdgeAttributesBuilder();
296 if (linkDesc.getIpv4InterfaceAddress() != null) {
297 builder.setLocalAddress(new IpAddress(new Ipv4Address(linkDesc.getIpv4InterfaceAddress())));
299 if (linkDesc.getIpv6InterfaceAddress() != null) {
300 builder.setLocalAddress(new IpAddress(new Ipv6Address(linkDesc.getIpv6InterfaceAddress())));
302 if (linkDesc.getIpv4NeighborAddress() != null) {
303 builder.setRemoteAddress(new IpAddress(new Ipv4Address(linkDesc.getIpv4NeighborAddress())));
305 if (linkDesc.getIpv6NeighborAddress() != null) {
306 builder.setRemoteAddress(new IpAddress(new Ipv6Address(linkDesc.getIpv6NeighborAddress())));
308 if (linkDesc.getLinkLocalIdentifier() != null) {
309 builder.setLocalIdentifier(linkDesc.getLinkLocalIdentifier());
311 if (linkDesc.getLinkRemoteIdentifier() != null) {
312 builder.setRemoteIdentifier(linkDesc.getLinkRemoteIdentifier());
314 if (la.getMetric() != null) {
315 builder.setMetric(la.getMetric().getValue());
317 if (la.getTeMetric() != null) {
318 builder.setTeMetric(la.getTeMetric().getValue());
320 if (la.getMaxLinkBandwidth() != null) {
321 builder.setMaxLinkBandwidth(bandwithToDecimalBandwidth(la.getMaxLinkBandwidth()));
323 if (la.getMaxReservableBandwidth() != null) {
324 builder.setMaxResvLinkBandwidth(bandwithToDecimalBandwidth(la.getMaxReservableBandwidth()));
326 if (la.getUnreservedBandwidth() != null) {
327 int upperBound = Math.min(la.getUnreservedBandwidth().size(), MAX_PRIORITY);
328 final List<UnreservedBandwidth> unRsvBw = new ArrayList<>(upperBound);
330 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120
331 .UnreservedBandwidth bandwidth : la.nonnullUnreservedBandwidth().values()) {
332 unRsvBw.add(new UnreservedBandwidthBuilder()
333 .setBandwidth(bandwithToDecimalBandwidth(bandwidth.getBandwidth()))
334 .withKey(new UnreservedBandwidthKey(bandwidth.getPriority())).build());
336 builder.setUnreservedBandwidth(unRsvBw);
338 if (la.getAdminGroup() != null) {
339 builder.setAdminGroup(la.getAdminGroup().getValue());
341 if (la.getLinkDelay() != null) {
342 builder.setDelay(new Delay(la.getLinkDelay().getValue()));
344 if (la.getLinkMinMaxDelay() != null && la.getLinkMinMaxDelay() != null) {
345 MinMaxDelay mmDelay = new MinMaxDelayBuilder()
346 .setMaxDelay(new Delay(la.getLinkMinMaxDelay().getMaxDelay().getValue()))
347 .setMinDelay(new Delay(la.getLinkMinMaxDelay().getMinDelay().getValue())).build();
348 builder.setMinMaxDelay(mmDelay);
350 if (la.getDelayVariation() != null) {
351 builder.setJitter(new Delay(la.getDelayVariation().getValue()));
353 if (la.getLinkLoss() != null) {
354 builder.setLoss(new Loss(la.getLinkLoss().getValue()));
356 if (la.getAvailableBandwidth() != null) {
357 builder.setAvailableBandwidth(bandwithToDecimalBandwidth(la.getAvailableBandwidth()));
359 if (la.getResidualBandwidth() != null) {
360 builder.setResidualBandwidth(bandwithToDecimalBandwidth(la.getResidualBandwidth()));
362 if (la.getUtilizedBandwidth() != null) {
363 builder.setUtilizedBandwidth(bandwithToDecimalBandwidth(la.getUtilizedBandwidth()));
365 if (la.getSharedRiskLinkGroups() != null) {
366 List<Uint32> srlgs = new ArrayList<>();
367 for (SrlgId srlg : la.getSharedRiskLinkGroups()) {
368 srlgs.add(srlg.getValue());
370 builder.setSrlgs(srlgs);
372 if (la.getSrAdjIds() != null) {
373 for (SrAdjIds adj : la.getSrAdjIds()) {
374 if (adj.getSidLabelIndex() instanceof LocalLabelCase) {
375 boolean backup = false;
376 if (adj.getFlags() instanceof OspfAdjFlags) {
377 backup = ((OspfAdjFlags) adj.getFlags()).isBackup();
379 if (adj.getFlags() instanceof IsisAdjFlags) {
380 backup = ((IsisAdjFlags) adj.getFlags()).isBackup();
383 builder.setAdjSid(((LocalLabelCase) adj.getSidLabelIndex()).getLocalLabel().getValue());
385 builder.setBackupAdjSid(((LocalLabelCase) adj.getSidLabelIndex()).getLocalLabel().getValue());
390 return builder.build();
394 * Get Node Attributes from Link State Route attributes.
396 * @param attributes The attribute part from the Link State route
398 * @return Node Attributes
400 private static NodeAttributes getNodeAttributes(final Attributes attributes) {
401 final NodeAttributes na;
402 final Attributes1 attr = attributes.augmentation(Attributes1.class);
404 final LinkStateAttribute attrType = attr.getLinkStateAttribute();
405 if (attrType != null) {
406 na = ((NodeAttributesCase) attrType).getNodeAttributes();
417 * Create Vertex from the Node Attributes.
419 * @param na Node Attributes
420 * @param cvertex Connected Vertex associated to this Vertex
421 * @param as As number
425 private static Vertex getVertex(final NodeAttributes na, final Uint64 id, final int as) {
426 VertexBuilder builder = new VertexBuilder().setVertexId(id).setAsn(Uint32.valueOf(as));
427 if (na.getIpv4RouterId() != null) {
428 builder.setRouterId(new IpAddress(new Ipv4Address(na.getIpv4RouterId().getValue())));
430 if (na.getIpv6RouterId() != null) {
431 builder.setRouterId(new IpAddress(new Ipv6Address(na.getIpv6RouterId().getValue())));
434 * Set Router Name with dynamic hostname (IS-IS) or IPv4 address in dot decimal format (OSPF)
436 if (na.getDynamicHostname() != null) {
437 builder.setName(na.getDynamicHostname());
439 int key = id.intValue();
441 (key << 24 & 0xFF) + "." + (key << 16 & 0xFF) + "." + (key << 8 & 0xFF) + "." + (key & 0xFF));
443 if (na.getSrCapabilities() != null) {
444 builder.setSrgb(new SrgbBuilder()
446 ((LocalLabelCase) na.getSrCapabilities().getSidLabelIndex()).getLocalLabel().getValue())
447 .setRangeSize(na.getSrCapabilities().getRangeSize().getValue())
450 if (na.getNodeFlags() != null) {
451 if (na.getNodeFlags().isAbr()) {
452 builder.setVertexType(VertexType.Abr);
454 if (na.getNodeFlags().isExternal()) {
455 builder.setVertexType(VertexType.AsbrOut);
458 builder.setVertexType(VertexType.Standard);
460 return builder.build();
464 * Create new Connected Vertex in the Connected Graph.
466 * @param value The complete Linkstate route information
467 * @param nodeCase The node part of the Linkstate route
468 * @param attributes The node attributes
470 private void createVertex(final LinkstateRoute value, final NodeCase nodeCase, final Attributes attributes) {
471 Preconditions.checkArgument(nodeCase != null, "Missing Node Case. Skip this Node");
472 Preconditions.checkArgument(nodeCase.getNodeDescriptors() != null, "Missing Node Descriptors. Skip this Node");
474 Uint64 vertexId = getVertexId(nodeCase.getNodeDescriptors().getCRouterIdentifier());
475 if (vertexId == Uint64.ZERO) {
476 LOG.warn("Unable to get Vertex Identifier from descriptor {}, skipping it", nodeCase.getNodeDescriptors());
480 NodeAttributes na = getNodeAttributes(attributes);
482 LOG.warn("Missing attributes in node {} route {}, skipping it", nodeCase, value);
487 if (nodeCase.getNodeDescriptors() != null) {
488 asNumber = nodeCase.getNodeDescriptors().getAsNumber().getValue().intValue();
490 Vertex vertex = getVertex(na, vertexId, asNumber);
492 /* Add the Connected Vertex and associated Vertex in the Graph */
493 LOG.info("Add Vertex {} in TED[{}]", vertex.getName(), cgraph);
494 cgraph.addVertex(vertex);
498 * Create new Prefix in the Connected Graph.
500 * @param value The complete Linkstate route information
501 * @param prefixCase The Prefix part of the Linkstate route
502 * @param attributes The Prefix attributes
504 private void createPrefix(final LinkstateRoute value, final PrefixCase prefixCase, final Attributes attributes) {
505 final IpPrefix ippfx = prefixCase.getPrefixDescriptors().getIpReachabilityInformation();
507 LOG.warn("IP reachability not present in prefix {} route {}, skipping it", prefixCase, value);
511 /* Verify that all mandatory information are present */
512 final PrefixAttributes pa;
513 final Attributes1 attr = attributes.augmentation(Attributes1.class);
515 final LinkStateAttribute attrType = attr.getLinkStateAttribute();
516 if (attrType != null) {
517 pa = ((PrefixAttributesCase) attrType).getPrefixAttributes();
519 LOG.warn("Missing attribute type in IP {} prefix {} route {}, skipping it", ippfx, prefixCase, value);
523 LOG.warn("Missing attributes in IP {} prefix {} route {}, skipping it", ippfx, prefixCase, value);
528 * Get Connected Vertex from Connected Graph corresponding to the
529 * Advertising Node Descriptor
531 Uint64 vertexId = getVertexId(prefixCase.getAdvertisingNodeDescriptors().getCRouterIdentifier());
532 if (vertexId == Uint64.ZERO) {
533 LOG.warn("Unable to get the Vertex Identifier from descriptor {}, skipping it",
534 prefixCase.getAdvertisingNodeDescriptors());
539 PrefixBuilder builder = new PrefixBuilder().setVertexId(vertexId);
540 if (pa.getSrPrefix() != null && pa.getSrPrefix().getSidLabelIndex() instanceof SidCase) {
541 builder.setPrefixSid(((SidCase) pa.getSrPrefix().getSidLabelIndex()).getSid());
542 if (pa.getSrPrefix().getFlags() instanceof IsisPrefixFlagsCase) {
544 ((IsisPrefixFlagsCase) pa.getSrPrefix().getFlags()).getIsisPrefixFlags().isNodeSid());
547 * Seems that OSPF Flags are not accessible. Assuming that the
548 * Prefix is a Node SID
550 builder.setNodeSid(true);
553 if (ippfx.getIpv4Prefix() != null) {
554 builder.setPrefix(new IpPrefix(ippfx.getIpv4Prefix()));
556 if (ippfx.getIpv6Prefix() != null) {
557 builder.setPrefix(new IpPrefix(ippfx.getIpv6Prefix()));
559 Prefix prefix = builder.build();
561 /* Add the Prefix to the Connected Vertex within the Connected Graph */
562 LOG.info("Add prefix {} in TED[{}]", builder.getPrefix(), cgraph);
563 cgraph.addPrefix(prefix);
567 protected void removeObject(final ReadWriteTransaction trans, final InstanceIdentifier<LinkstateRoute> id,
568 final LinkstateRoute value) {
570 LOG.error("Empty before-data received in delete data change notification for instance id {}", id);
574 final ObjectType t = value.getObjectType();
575 if (t instanceof LinkCase) {
576 removeEdge((LinkCase) t);
577 } else if (t instanceof NodeCase) {
578 removeVertex((NodeCase) t);
579 } else if (t instanceof PrefixCase) {
580 removePrefix((PrefixCase) t);
582 LOG.debug(UNHANDLED_OBJECT_CLASS, t.implementedInterface());
586 private void removeEdge(final LinkCase linkCase) {
587 /* Get Source and Destination Connected Vertex */
588 if (linkCase.getLinkDescriptors() == null) {
589 LOG.warn("Missing Link descriptor in link {}, skipping it", linkCase);
592 EdgeKey edgeKey = new EdgeKey(getEdgeId(linkCase));
593 if (edgeKey == null || edgeKey.getEdgeId() == Uint64.ZERO) {
594 LOG.warn("Unable to get the Edge Key from link {}, skipping it", linkCase);
598 LOG.info("Deleted Edge {} from TED[{}]", edgeKey, cgraph);
599 cgraph.deleteEdge(edgeKey);
602 private void removeVertex(final NodeCase nodeCase) {
603 VertexKey vertexKey = new VertexKey(getVertexId(nodeCase.getNodeDescriptors().getCRouterIdentifier()));
604 if (vertexKey == null || vertexKey.getVertexId() == Uint64.ZERO) {
605 LOG.warn("Unable to get Vertex Key from descriptor {}, skipping it", nodeCase.getNodeDescriptors());
609 LOG.info("Deleted Vertex {} in TED[{}]", vertexKey, cgraph);
610 cgraph.deleteVertex(vertexKey);
613 private void removePrefix(final PrefixCase prefixCase) {
614 final IpPrefix ippfx = prefixCase.getPrefixDescriptors().getIpReachabilityInformation();
616 LOG.warn("IP reachability not present in prefix {}, skipping it", prefixCase);
620 LOG.info("Deleted prefix {} in TED[{}]", ippfx, cgraph);
621 cgraph.deletePrefix(ippfx);
625 * Get Vertex in the Graph by the OSPF Router ID or IS-IS-System ID.
627 * @param routerID The Router Identifier entry
629 * @return Vertex in the Connected Graph that corresponds to this Router ID. Vertex is created if not found.
631 private static Uint64 getVertexId(final CRouterIdentifier routerID) {
634 if (routerID instanceof IsisNodeCase) {
635 byte[] isoId = ((IsisNodeCase) routerID).getIsisNode().getIsoSystemId().getValue();
636 final byte[] convert = {0, 0, isoId[0], isoId[1], isoId[2], isoId[3], isoId[4], isoId[5]};
637 rid = ByteBuffer.wrap(convert).getLong();
639 if (routerID instanceof OspfNodeCase) {
640 rid = ((OspfNodeCase) routerID).getOspfNode().getOspfRouterId().longValue();
643 LOG.debug("Get Vertex Identifier {}", rid);
644 return Uint64.valueOf(rid);
647 private static DecimalBandwidth bandwithToDecimalBandwidth(final Bandwidth bw) {
648 return new DecimalBandwidth(BigDecimal.valueOf(ByteBuffer.wrap(bw.getValue()).getFloat()));
651 private static long ipv4ToKey(final String str) {
654 ip = ((Inet4Address) Inet4Address.getByName(str)).getAddress();
655 } catch (UnknownHostException e) {
658 return (0xFF & ip[0]) << 24 | (0xFF & ip[1]) << 16 | (0xFF & ip[2]) << 8 | 0xFF & ip[3];
661 private static Long ipv6ToKey(final String str) {
664 ip = ((Inet6Address) Inet6Address.getByName(str)).getAddress();
665 } catch (UnknownHostException e) {
668 /* Keep only the lower 64bits from the IP address */
669 byte[] lowerIP = {ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]};
670 return ByteBuffer.wrap(lowerIP).getLong();
674 protected InstanceIdentifier<LinkstateRoute> getRouteWildcard(final InstanceIdentifier<Tables> tablesId) {
675 return tablesId.child(LinkstateRoutesCase.class, LinkstateRoutes.class).child(LinkstateRoute.class);
679 protected void clearTopology() {